; 	
;       $Log: selftest.asm,v $
;       Revision 1.6  2000/10/31
;       modification in selftest file
;
;       Revision 1.5  2000/02/23
;       changes in the exit address of the program
;
;       Revision 1.4  2000/02/23
;       changes in the wait state generator
;
	list on
	symbols
;	Assembler directive for standard part memory model
	CHIP	8052
;	*******************************************************
;							
;		  M8051EW SELFTEST
;							
;	*******************************************************
;   Copyright (c) Mentor Graphics Corporation, 1991-2001, All Rights Reserved.
;                        UNPUBLISHED, LICENSED SOFTWARE.
;             CONFIDENTIAL AND PROPRIETARY INFORMATION WHICH IS THE
;           PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS.
;
;	title selftest.asm: 10 February 2000 - general instruction test module
;	
;	MODULE FUNCTION
;	---------------

;
;	This is the main selftest program used for the test of the m8051ew
;	8-bit microcontroller. This programme provides a self test and works
;	in conjuction with the configuration file of the m8051EW.
;	The user can change the configuration file m8051ewarp_cfg.v(hd) 
;	and perform simulation. When this programme reaches the address 20FFh
;	there are no errors in the opration of the M8051EW.
;
;	This module demonstrates the instruction set and hardware functions of
;	the M8051EW Soft Core, giving a high level of code coverage.
	page
;	
;	INCLUDE FILES
;	-------------
;
	list	off
	include ../include/defines.inc
	include ../include/ramdata.inc
	include	../include/romdata.inc
	include ../include/macro.inc
	include ../include/testdata.inc
	include ../include/esfr.inc
	include ../include/selftest.inc
	list	on
;
; LOCAL DEFINITIONS
; -----------------
;
tick			equ	252	; timer/counter time constant is 4 ticks
;
; interrupt flags - interrupt has occurred registers
;
;
int_counter		equ	3fh
i0_int_flag		equ	40h	
t0_int_flag		equ	41h
i1_int_flag		equ	42h
t1_int_flag		equ	43h
tr_int_flag		equ	44h
ext05_int_flag		equ	45h
ext06_int_flag		equ	46h
ext07_int_flag		equ	47h
ext08_int_flag		equ	48h
ext09_int_flag		equ	49h
ext10_int_flag		equ	4ah
ext11_int_flag		equ	4bh
ext12_int_flag		equ	4ch
ext13_int_flag		equ	4dh
nmi_int_flag            equ     4eh
nmi_counter             equ     4fh


; ===========
; ENTRY POINT
; ===========
;
	org	orgems
	ajmp	inittest		; skip over vectors to start of tests
;
; checksum
; --------
;
	org	orgcs
csbyte	db	0			; reserved for checksum byte
;
; external interrupt 0 (INT0) service routine
; -------------------------------------------
;
	org	Int0_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 ie.0 reset
;
	clr	ie.0			; disable further external 1 interrupts
	jmp     ie0_irq                 ; jump to the interrupt service routine 	
;
; timer 0 interrupt service routine
; ---------------------------------
;
	org	timer0_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie.1 reset
;
	clr	ie.1			; disable further timer 0 interrupts
	jmp     tf0_irq                 ; jump to the interrupt service routine
; external interrupt 1 (INT1) service routine
; -------------------------------------------
;
	org	Int1_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 ie.2 reset
;
	clr	ie.2			; disable further external 1 interrupts
	jmp     ie1_irq                 ; jump to the interrupt service routine
; timer 1 interrupt service routine
; ---------------------------------
;
	org	timer1_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie.3 reset
;
	clr	ie.3			; disable further timer 1 interrupts
	jmp     tf1_irq                 ; jump to the interrupt service routine
; serial interface interrupt service routine
; ------------------------------------------
;
	org	serial_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie.4 reset
;
	clr	ie.4			; disable further serial interrupts
	jmp     ser_irq                 ; jump to the interrupt service routine
; external interrupt  5 service routine
; -------------------------------------
;
	org	Int5_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie.5 reset
;
	clr	ie.5			; disable further external  5 or TIMER2 interrupts
	jmp     ie5_irq                 ; jump to the interrupt service routine
; external interrupt  6 service routine
; -------------------------------------
;
	org	Int6_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie1.0 reset
;
	clr	ie1.0			; disable further external  6 interrupts
	jmp     ie6_irq                 ; jump to the interrupt service routine
; external interrupt  7 service routine
; -------------------------------------
;
	org	Int7_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie1.1 reset
;
	clr	ie1.1			; disable further external  7 interrupts
	jmp     ie7_irq                 ; jump to the interrupt service routine
; external interrupt  8 service routine
; -------------------------------------
;
	org	Int8_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie1.2 reset
;
	clr	ie1.2			; disable further external  8 interrupts
	jmp     ie8_irq                 ; jump to the interrupt service routine
; external interrupt  9 service routine
; -------------------------------------
;
	org	Int9_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie1.3 reset
;
	clr	ie1.3			; disable further external  9 interrupts
	jmp     ie9_irq                 ; jump to the interrupt service routine
	;
; external interrupt 10 service routine
; -------------------------------------
;
	org	Int10_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie1.4 reset
;
	clr	ie1.4			; disable further external 10 interrupts
	jmp     ie10_irq                ; jump to the interrupt service routine
; external interrupt 11 service routine
; -------------------------------------
;
	org	Int11_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie1.5 reset
;
	clr	ie1.5			; disable further external 11 interrupts
	jmp     ie11_irq                ; jump to the interrupt service routine
; external interrupt 12 service routine
; -------------------------------------
;
	org	Int12_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie1.6 reset
;
	clr	ie1.6			; disable further external 12 interrupts
	jmp     ie12_irq                ; jump to the interrupt service routine
; external interrupt 13 service routine
; -------------------------------------
;
	org	Int13_rt
;
; indicate that this interrupt has occurred by clearing corresponding enable bit
;
; entry: no conditions
; exit:	 flags, a preserved, ie1.7 reset
;
	clr	ie1.7			; disable further external 13 interrupts
	jmp     ie13_irq                ; jump to the interrupt service routine
; NMI interrupt service routine
; ------------------------------
;
	org	NMI_rt
	jmp	nmi_irq                  ; jump to the interrupt service routine
	
		org	Program_Start_Address
	;------------------------------------------------------------------------
	;                   IE0 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ie0_irq:mov	i0_int_flag, int_counter; save service counter for priority test
	inc	int_counter		; increment service counter
	jb      b.0,ie0_r               ; jump to another interrupt service routine
                                        ; to triger all the interrupts
	reti				; return from interrupt
ie0_r:	jmp	irq
	;------------------------------------------------------------------------
	;                   TIMER0 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
tf0_irq:mov	t0_int_flag, int_counter; save service counter for priority test
	inc	int_counter		; increment service counter
	jb      b.0,tf0_r               ; jump to another interrupt service routine
                                        ; to triger all the interrupts
	reti				; return from interrupt
tf0_r:	jmp	irq
	;------------------------------------------------------------------------
	;                   IE1 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------	
ie1_irq:mov	i1_int_flag, int_counter; save service counter for priority test
	inc	int_counter		; increment service counter
	jb      b.0,ie1_r               ; jump to another interrupt service routine
                                        ; to trigger all the interrupts 
	reti				; return from interrupt
ie1_r:  jmp	irq
	;------------------------------------------------------------------------
	;                   TIMER1 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
tf1_irq:mov	t1_int_flag, int_counter; save service counter for priority test
	inc	int_counter		; increment service counter
	jb      b.0,tf1_r               ; jump to another interrupt service routine
                                        ; to trigger all the interrupts
	reti				; return from interrupt
tf1_r:  jmp	irq
	;------------------------------------------------------------------------
	;                   SERIAL INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ser_irq:mov	tr_int_flag, int_counter; save service counter for priority test
	inc	int_counter		; increment service counter
	jb      b.0,irq                 ; jump to another interrupt service routine
                                        ; to trigger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                   IE5/TIMER2 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ie5_irq:mov	ext05_int_flag, int_counter; save interrupts serviced count
	inc	int_counter		; increment service counter
	jb      b.0, irq                ; jump to another interrupt service routine
                                        ; to triger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                   IE6 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ie6_irq:mov	ext06_int_flag, int_counter; save interrupts serviced count
	inc	int_counter		; increment service counter
	jb      b.0,irq                 ; jump to another interrupt service routine
                                        ; to trigger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                   IE7 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ie7_irq:mov	ext07_int_flag, int_counter; save interrupts serviced count
	inc	int_counter		; increment service counter
	jb      b.0, irq                ; jump to another service routine 
                                        ; to triger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                   IE8 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ie8_irq:mov	ext08_int_flag, int_counter; save interrupts serviced count
	inc	int_counter		; increment service counter
	jb      b.0, irq                ; jump to another service routine
                                        ; to trigger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                   IE9 INTERRUPT SERVICE ROUTINE 
	;------------------------------------------------------------------------
ie9_irq:mov	ext09_int_flag, int_counter; save interrupts serviced count
	inc	int_counter		; increment service counter
	jb      b.0, irq                ; jump to another service routine
                                        ; to trigger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                   IE10 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ie10_irq:mov	ext10_int_flag, int_counter; save interrupts serviced count
	inc	int_counter		; increment service counter
	jb      b.0, irq                ; jump to another service routine
                                        ; to trigger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                   IE11 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ie11_irq:mov	ext11_int_flag, int_counter; save interrupts serviced count
	inc	int_counter		; increment service counter
	jb      b.0, irq                ; jump to another service routine
                                        ; to trigger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                   IE12 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ie12_irq:mov	ext12_int_flag, int_counter; save interrupts serviced count
	inc	int_counter		; increment service counter
	jb      b.0, irq                ; jump to another service routine
                                        ; to trigger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                   IE13 INTERRUPT SERVICE ROUTINE
	;------------------------------------------------------------------------
ie13_irq:mov	ext13_int_flag, int_counter; save interrupts serviced count
	inc	int_counter		; increment service counter
	jb      b.0,irq                 ; jump to another service routine
                                        ; to trigger all the interrupts
	reti				; return from interrupt
	;------------------------------------------------------------------------
	;                         NMI SERVICE ROUTINE
	;------------------------------------------------------------------------
nmi_irq:mov	nmi_int_flag, nmi_counter;copy nmi_counter bit to nmi_int_flag
	inc     nmi_counter              ;increment service counter
	jb	b.1,nmi_iq               ;if B.1=1 jump to nmi_iq
	reti                             ;return from interrupt
nmi_iq: mov	b,#0                     ;clear the B register to avoid loops
	mov     xintr1,#00h              ;clear the trigerring of the NMI
	nop
	nop
	nop
	nop
	nop
	mov     xintr1,#80h              ;triger NMI through the esfr XINTR1 register
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop				 ;introduce some delay
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	reti				;return from interrupt
	;------------------------------------------------------------------------
	; INTERRUPT SERVICE ROUTINE TO TRIGER ALL THE INTERRUPTS SIMULTANEOUSLY
	;------------------------------------------------------------------------

irq:    clr	b.0			;clear the global flag B.0 that indicates
                                        ;the interrupt service routine should 
                                        ;trigger all the interrupts
	mov     ie,#00h                 ;disable all interrupts
	mov     ie1,#00h                ;disable all interrupts
	mov     xintr1,#01h            ;trigger IE13 external interrupt
	mov     xintr0,#ffh            ;trigger IE12 to IE5 external interrupts
	mov     scon,#03h               ;trigger the serial interface interrupt
	mov     tcon,#afh               ;triger ie0, tf0, ie1, tf1 interrupts
	mov	A,config_reg1           ;copy config_reg1 to Acc register
	jb	A.0, abd                ;If TIMER2 is not included continue
	setb    tf2                     ;trigger TIMER2 interrupt
abd:	mov     ie1,#ffh                ;enable all interrupts
	mov     ie,#bfh                 ;enable all interrupts
	nop
	nop
	nop
	nop
	nop				;introduce some delay 
	nop
	nop
	nop
	nop
	mov     A,config_reg1           ;copy config_reg1 to Acc register
	jb      A.0, abf                ;if timer2 is not included continue
	clr     tf2                     ;do not trigger TIMER2 interrupt
abf:	reti				;return from interrupt

;========
inittest:
;========
;
; start routine
;
; entry: no conditions
;  exit: all registers and flags corrupt
;
;=========
resettest:
;=========
;
; test that register are as they should be
;
; entry: no conditions
;  exit: flags other registers corrupt
;
;
; check that accumulator is 0
;
	jz	$rst1		;j if acc equal to zero
	error	E_rst_accnotzero	;failed if acc not zero
;
; check that b register is 0
;
$rst1:	mov	a, b		;fetch contents of b
	jz	$rst2		;j if b reg equal to zero
	error	E_rst_bregnotzero	;failed if acc not zero
;
; check that flags are 0
;
$rst2:	mov	a, psw		;get flags
	jz	$rst3		;j if flags equal to zero
	error	E_rst_pswnotzero	;failed if acc not zero
;
; check that the stack pointer is 7
;
$rst3:	mov	a, sp		;fetch stack pointer
	cjne	a, #07, $rst4	;failed if not = 7
	sjmp	$rst5		;j if ok
;
$rst4:	error	E_rst_spnoteq7
;
; check that high and low bytes of data ptr are 0
;
$rst5:	mov	a, dpl		;fetch low data ptr byte
	jz	$rst6		;j if dataptr = 0
	error	E_rst_dptr_low	;failed if data ptr low not equal 0
;
$rst6:	mov	a, dph		;fetch high data ptr byte
	jz	$rst11		;j if data ptr high = 0
	error	E_rst_dptr_high	;failed if data ptr high not equal 0
;
; check that there is ff on all ports
;
;
; check interrupt priority is 0
;
$rst11:	mov	a, ip		;fetch ip flag
	anl	a, #(bit4 + bit3 + bit2 + bit1 + bit0)
	jz	$rst12		;j if zero
	error	E_rst_ipnotzero	;failed if ip not equal to 0
;
; check interrupt enable is 0
;
$rst12	mov	a, ie		;fetch interrupt enable flag
	anl	a, #(bit7 + bit4 + bit3 + bit2 + bit1 + bit0)
	jz	$rst13		;j if zero
	error	E_rst_ienotzero	;failed if ie not equal to 0
;
; check timer mode register is 0
;
$rst13	mov	a, tmod		;fetch timer mode contents
	jz	$rst14		;j if zero
	error	E_rst_tmodnotzero	;failed if tmod not equal to 0
;
; check timer control register is 0
;
$rst14	mov	a, tcon		;fetch timer control contents
	jz	$rst15		;j if zero
	error	E_rst_tconnotzero	;failed if tcon not equal to 0
;
; check timer / counter 0 high and low bytes equal 0
;
$rst15:	mov	a, tl0
	jz	$rst16		;j if ok
	error	E_rst_tl0_notzero	;failed if timer counter 1 low <> 0
;
$rst16	mov	a, th0
	jz	$rst17		;j if ok
	error	E_rst_th0_notzero	;failed if timer counter 0 high <> 0
;
; check timer / counter 1 high and low bytes equal 0
;
$rst17:	mov	a, tl1
	jz	$rst18		;j if ok
	error	E_rst_tl1_notzero	;failed if timer counter 1 low <> 0
;
$rst18	mov	a, th1
	jz	$rst19		;j if ok
	error	E_rst_th1_notzero	;failed if timer counter 1 high <> 0
;
; check serial control register is 0
;
$rst19:	mov	a, scon
	jz	$rst20		;ok
	error	E_rst_scon_notzero	;failed if scon not equal 0
;
; check power control register
;
$rst20:	mov	a, pcon
	anl	a, #(bit7)
	jz	ports_tst		;ok
	error	E_rst_pcon_notzero	;failed if pcon not equal 0
	;---------------------------------------------------------------------------
	;                             PORTS TEST
	;---------------------------------------------------------------------------
ports_tst:
	mov	a,config_reg		;Copy config_reg to Acc
	jb	a.2,dtst               ;Continue the test if Acc.2=1
	sjmp	ports_tst1
dtst:   jmp	dptrm_tst
ports_tst1:
	clr     a                       ; clear the Accumulator
	inc	p0			; force a register read
	cjne	a, p0, $errp1		; check pins for zero
	inc	p1
	dec	p0			; restore inactive levels
	cjne	a, p1, $errp2		; check pins for zero
	inc	p2
	dec	p1			; restore inactive levels
	cjne	a, p2, $errp3		; check pins for zero
	inc	p3
	dec	p2			; restore inactive levels
	cjne	a, p3, $errp4		; check pins for zero
	dec	p3			; restore inactive levels
	sjmp	testp1      		; pass on to the next test
$errp1:	sjmp    $errp1	                ; port1 error trap
$errp2:  sjmp    $errp2                   ; port2 error trap
$errp3:  sjmp    $errp3                   ; port3 error trap
$errp4:  sjmp    $errp4                   ; port4 error trap
        ;---------------------------------------------------------------
	;                        TEST OF PORT0
	;---------------------------------------------------------------
testp1:  mov     p0, #1fh                ; write 1fh to port 0
	mov     r0, p0
	cjne    r0, #1fh, errp5         ; check port 0
	mov	p0,#30h                 ;load Port0 with 30h
	anl     p0,#20h                 ;P0=30H AND 20h
        mov	a,#20h                  ;load Acc with the expected result
	cjne    a,p0,errp6              ;compare with port0
	sjmp    tstp1
errp5:	sjmp    errp5	                ; port0 error 
errp6:   sjmp    errp6                    ; ANL-Port0 error

tstp1:	orl     p0,#50h                 ;P0=20H OR 50H
	mov     a,#70h                  ;load Acc with the expected result
	cjne    a,p0,errp7              ;compare with port0
	xrl     p0,#50h                 ;P0=70H XOR 50H
	mov     a,#20h                  ;load Acc with the expected result
	cjne    a,p0,errp8              ;compare with port0
	mov     a,#10h                  ;load Acc with 10h
	add     a,p0                    ; A=10h+20h
	cjne    a,#30h,errp9            ;compare with 30h
	setb    c     			;set carry
	mov     p0,#20h                 ;load port0 with 20h
	mov     a,#30h                  ;load Acc with 30h
	addc    a,p0                    ; A=30h+20h+1
	cjne    a,#51h,errp10           ;compare with 51h
	subb    a,p0                    ; A=51h-20h
	cjne    a,#31h,errp11           ;compare with 31h
	push	p0                      ;PUSH port0
	pop     p0                      ;POP  port0
	mov     a,#20h                  ;load Acc with the expected result
	cjne    a,p0,errp12             ;compare with port0
	inc     p0                      ;increment Port0
	mov     a,#21h                  ;load Acc with the expected result
	cjne    a,p0,errp13             ;compare with Port0
	dec     p0                      ;decrement Port0
	mov     a,#20h                  ;load Acc with expected result
	cjne    a,p0,errp14             ;compare with Port0
	setb    p0.0                    ;set bit0 of Port0
	mov     a,#21h                  ;load Acc with expected result
	cjne    a,p0,errp15             ;compare with Port0	
	clr     p0.0                    ;clear bit0 of Port0
	mov     a,#20h                  ;load Acc with expected result
	cjne    a,p0,errp16             ;compare with Port0
	cpl     p0.0                    ;invert bit0 of Port0
	mov     a,#21h                  ;load Acc with expected result
	cjne    a,p0,errp17             ;compare with Port0
	jb      p0.0,testp2              ;jump if bit0 is one
$errp18: sjmp    $errp18                  ; JB-Port0 error
testp2:  cjne    a,p0,errp19             ;compare with Port0
	jbc     p0.0,testp3              ;jump if bit0 is one and clear bit0
$errp20: sjmp    $errp20                  ; JBC-Port0 error
testp3:  mov     a,#20h                  ;load Acc with expected result
	cjne    a,p0,errp21             ;compare with Port0
	djnz    p0,testp4                ;decrement Port0 and jump if its no-zero
$errp22: sjmp    $errp22                  ; DJNZ-Port0 error
testp4:  mov     a,#1Fh                  ;load Acc with expected result
	cjne    a,p0,errp23             ;compare with Port0
	mov     p0,#01h                 ;load port0 with 1
	djnz    p0,errp24               ;decrement Port0 and jump if its no-zero
	mov     a,#10h                  ;load Acc with 10h
	xch     a,p0                    ;exchange data between port0 and Acc
	cjne    a,#0,errp25           ;compare Acc with 0
	mov     a,#10h                  ;load Acc with expected result
	cjne    a,p0,errp26             ;compare with Port        
	sjmp    port1                   ;continue the testing


errp7:   sjmp    errp7                    ; ORL-Port0 error
errp8:   sjmp    errp8                    ; XRL-Port0 error
errp9:   sjmp    errp9                    ; ADD-Port0 error
errp10:  sjmp    errp10                   ; ADDC-Port0 error
errp11:  sjmp    errp11                   ; SUBB-Port0 error
errp12:  sjmp    errp12                   ; PUSH-POP-Port0 error
errp13:  sjmp    errp13                   ; INC-Port0 error
errp14:  sjmp    errp14                   ; DEC-Port0 error
errp15:  sjmp    errp15                   ; SETB-Port0 error
errp16:  sjmp    errp16                   ; CLR-Port0 error
errp17:  sjmp    errp17                   ; CPL-Port0 error
errp19:  sjmp    errp19                   ; JB-Port0 error
errp21:  sjmp    errp21                   ; JBC-Port0 error
errp23:  sjmp    errp23                   ; DJNZ-Port0 error
errp24:  sjmp    errp24                   ; DJNZ-Port0 error
errp25:  sjmp    errp25                   ; XCH-Port0-Acc error
errp26:  sjmp    errp26                   ; XCH-Port0-Acc error
	;---------------------------------------------------------------
	;                        TEST OF PORT 1       
	;---------------------------------------------------------------
port1:  mov     p1, #1fh                ; write 1fh to port 1
	mov     r0, p1                  ; load R0 with the contents of Port1
	cjne    r0, #1fh, errp27          ; check port 1
	mov	p1,#30h                 ;load Port1 with 30h
	anl     p1,#20h                 ;P1=30H AND 20h
        mov	a,#20h                  ;load Acc with the expected result
	cjne    a,p1,errp28              ;compare with Port1
	sjmp    tstp2
errp27:	sjmp    errp27	                ; Port1 error 
errp28:  sjmp    errp28                   ; ANL-Port1 error

tstp2:	orl     p1,#50h                 ;P1=20H OR 50H
	mov     a,#70h                  ;load Acc with the expected result
	cjne    a,p1,errp29              ;compare with Port1
	xrl     p1,#50h                 ;P1=70H XOR 50H
	mov     a,#20h                  ;load Acc with the expected result
	cjne    a,p1,errp30              ;compare with Port1
	mov     a,#10h                  ;load Acc with 10h
	add     a,p1                    ; A=10h+20h
	cjne    a,#30h,errp31            ;compare with 30h
	setb    c     			;set carry
	mov     p1,#20h                 ;load port0 with 20h
	mov     a,#30h                  ;load Acc with 30h
	addc    a,p1                    ; A=30h+20h+1
	cjne    a,#51h,errp32            ;compare with 51h
	subb    a,p1                    ; A=51h-20h
	cjne    a,#31h,errp33            ;compare with 31h
	push	p1                      ;PUSH Port1
	pop     p1                      ;POP  Port1
	mov     a,#20h                  ;load Acc with the expected result
	cjne    a,p1,errp34              ;compare with port1
	inc     p1                      ;increment Port1
	mov     a,#21h                  ;load Acc with the expected result
	cjne    a,p1,errp35              ;compare with Port1
	dec     p1                      ;decrement Port1
	mov     a,#20h                  ;load Acc with expected result
	cjne    a,p1,errp36              ;compare with Port1
	setb    p1.0                    ;set bit0 of Port1
	mov     a,#21h                  ;load Acc with expected result
	cjne    a,p1,errp37              ;compare with Port1	
	clr     p1.0                    ;clear bit0 of Port1
	mov     a,#20h                  ;load Acc with expected result
	cjne    a,p1,errp38              ;compare with Port1
	cpl     p1.0                    ;invert bit0 of Port1
	mov     a,#21h                  ;load Acc with expected result
	cjne    a,p1,errp39              ;compare with Port1
	jb      p1.0,port1_test2        ;jump if bit0 is one
$errp40: sjmp    $errp40                  ; JB-Port1 error
port1_test2:  cjne    a,p1,errp41        ;compare with Port1
	jbc     p1.0,port1_test3        ;jump if bit0 is one and clear bit0
$errp42: sjmp    $errp42                  ; JBC-Port1 error
port1_test3:  mov     a,#20h            ;load Acc with expected result
	cjne    a,p1,errp43              ;compare with Port1
	djnz    p1,port1_test4          ;decrement Port1 and jump if its no-zero
$errp44: sjmp    $errp44                  ; DJNZ-Port1 error
port1_test4:  mov     a,#1Fh            ;load Acc with expected result
	cjne    a,p1,errp45              ;compare with Port1
	mov     p1,#01h                 ;load port1 with 1
	djnz    p1,errp46                ;decrement Port1 and jump if its no-zero
	mov     a,#10h                  ;load Acc with 10h
	xch     a,p1                    ;exchange data between port1 and Acc
	cjne    a,#0,errp47              ;compare Acc with 0
	mov     a,#10h                  ;load Acc with expected result
	cjne    a,p1,errp48              ;compare with Port1        
	sjmp    port2                   ;continue the testing


errp29:   sjmp    errp29                  ; ORL-Port1 error
errp30:   sjmp    errp30                  ; XRL-Port1 error
errp31:   sjmp    errp31                  ; ADD-Port1 error
errp32:  sjmp    errp32                   ; ADDC-Port1 error
errp33:  sjmp    errp33                   ; SUBB-Port1 error
errp34:  sjmp    errp34                   ; PUSH-POP-Port1 error
errp35:  sjmp    errp35                   ; INC-Port1 error
errp36:  sjmp    errp36                   ; DEC-Port1 error
errp37:  sjmp    errp37                   ; SETB-Port1 error
errp38:  sjmp    errp38                   ; CLR-Port1 error
errp39:  sjmp    errp39                   ; CPL-Port1 error
errp41:  sjmp    errp41                   ; JB-Port1 error
errp43:  sjmp    errp43                   ; JBC-Port1 error
errp45:  sjmp    errp45                   ; DJNZ-Port1 error
errp46:  sjmp    errp46                   ; DJNZ-Port1 error
errp47:  sjmp    errp47                   ; XCH-Port1-Acc error
errp48:  sjmp    errp48                   ; XCH-Port1-Acc error
	;---------------------------------------------------------------
	;                        TEST OF PORT 2       
	;---------------------------------------------------------------
port2:	mov     p2, #1fh                ; write 1fh to port 2
	mov     r0, p2                  ; load R0 with the contents of Port2
	cjne    r0, #1fh, errp49         ; check port 2
	mov	p2,#30h                 ;load Port2 with 30h
	anl     p2,#20h                 ;P2=30H AND 20h
        mov	a,#20h                  ;load Acc with the expected result
	cjne    a,p2,errp50              ;compare with Port2
	sjmp    tst3
errp49:	sjmp    errp49	                ; Port2 error 
errp50:  sjmp    errp50                   ; ANL-Port2 error

tst3:	orl     p2,#50h                 ;P2=20H OR 50H
	mov     a,#70h                  ;load Acc with the expected result
	cjne    a,p2,errp51              ;compare with Port2
	xrl     p2,#50h                 ;P2=70H XOR 50H
	mov     a,#20h                  ;load Acc with the expected result
	cjne    a,p2,errp52              ;compare with Port2
	mov     a,#10h                  ;load Acc with 10h
	add     a,p2                    ; A=10h+20h
	cjne    a,#30h,errp53            ;compare with 30h
	setb    c     			;set carry
	mov     p2,#20h                 ;load port2 with 20h
	mov     a,#30h                  ;load Acc with 30h
	addc    a,p2                    ; A=30h+20h+1
	cjne    a,#51h,errp54            ;compare with 51h
	subb    a,p2                    ; A=51h-20h
	cjne    a,#31h,errp55            ;compare with 31h
	push	p2                      ;PUSH Port2
	pop     p2                      ;POP  Port2
	mov     a,#20h                  ;load Acc with the expected result
	cjne    a,p2,errp56              ;compare with port2
	inc     p2                      ;increment Port2
	mov     a,#21h                  ;load Acc with the expected result
	cjne    a,p2,errp57              ;compare with Port2
	dec     p2                      ;decrement Port2
	mov     a,#20h                  ;load Acc with expected result
	cjne    a,p2,errp58              ;compare with Port2
	setb    p2.0                    ;set bit0 of Port2
	mov     a,#21h                  ;load Acc with expected result
	cjne    a,p2,errp59              ;compare with Port2	
	clr     p2.0                    ;clear bit0 of Port2
	mov     a,#20h                  ;load Acc with expected result
	cjne    a,p2,errp60              ;compare with Port2
	cpl     p2.0                    ;invert bit0 of Port2
	mov     a,#21h                  ;load Acc with expected result
	cjne    a,p2,errp61              ;compare with Port2
	jb      p2.0,port2_test2        ;jump if bit0 is one
$errp62: sjmp    $errp62                  ; JB-Port2 error
port2_test2:  cjne    a,p2,errp63        ;compare with Port2
	jbc     p2.0,port2_test3        ;jump if bit0 is one and clear bit0
$errp64: sjmp    $errp64                  ; JBC-Port2 error
port2_test3:  mov     a,#20h            ;load Acc with expected result
	cjne    a,p2,errp65              ;compare with Port2
	djnz    p2,port2_test4           ;decrement Port2 and jump if its no-zero
$errp66: sjmp    $errp66                 ; DJNZ-Port2 error
port2_test4:  mov     a,#1Fh             ;load Acc with expected result
	cjne    a,p2,errp67              ;compare with Port2
	mov     p2,#01h                  ;load port2 with 1
	djnz    p2,errp68                ;decrement Port2 and jump if its no-zero
	mov     a,#10h                   ;load Acc with 10h
	xch     a,p2                     ;exchange data between port2 and Acc
	cjne    a,#0,errp69              ;compare Acc with 0
	mov     a,#10h                   ;load Acc with expected result
	cjne    a,p2,errp70              ;compare with Port2        
	jmp     dptrm_tst                ;continue the testing


errp51:   sjmp    errp51                  ; ORL-Port2 error
errp52:   sjmp    errp52                  ; XRL-Port2 error
errp53:   sjmp    errp53                  ; ADD-Port2 error
errp54:  sjmp    errp54                   ; ADDC-Port2 error
errp55:  sjmp    errp55                   ; SUBB-Port2 error
errp56:  sjmp    errp56                   ; PUSH-POP-Port2 error
errp57:  sjmp    errp57                   ; INC-Port2 error
errp58:  sjmp    errp58                   ; DEC-Port2 error
errp59:  sjmp    errp59                   ; SETB-Port2 error
errp60:  sjmp    errp60                   ; CLR-Port2 error
errp61:  sjmp    errp61                   ; CPL-Port2 error
errp63:  sjmp    errp63                   ; JB-Port2 error
errp65:  sjmp    errp65                   ; JBC-Port2 error
errp67:  sjmp    errp67                   ; DJNZ-Port2 error
errp68:  sjmp    errp68                   ; DJNZ-Port2 error
errp69:  sjmp    errp69                   ; XCH-Port2-Acc error
errp70:  sjmp    errp70                   ; XCH-Port2-Acc error
	;---------------------------------------------------------------
	;                        TEST OF PORT 3       
	;---------------------------------------------------------------
	;the test of Port3 takes place individually in the file ports.asm
	;when the user uses that test to test port 3 he shoule disable
	;the feedback Receive Data <= Transmit data of the UART included
	;in the test bench tb_ports.v for verilog or VHDL co-simulation
        ;---------------------------------------------------------------------------
	;                          DPTR MAPPED TEST
	;---------------------------------------------------------------------------
dptrm_tst:
	mov	a,config_reg		;Copy config_reg to Acc
	jb	a.3,dptrm_tst1		;Jump to dptrm_tst1 if Acc.3=1
	jmp	dptrb_tst		;continue the test
dptrm_tst1:
	
        ;-------------------------------------------------------------
	;                     INITIALIZATION TEST
	;-------------------------------------------------------------
test_dptrm:   
        mov	a,dph		;the Acc loads the contents of the DPH
	cjne    a,#0,$errm1     ;compares Acc with zero
        mov	a,dpl		;the Acc loads the contents of the DPL
	cjne	a,#0,$errm2     ;compares Acc with zero
	mov	a,dph1          ;the Acc loads the contents of the DPH1
	cjne    a,#0,$errm3     ;compares Acc with zero
	mov	a,dpl1          ;the Acc loads the contents of the DPL1
	cjne    a,#0,$errm4     ;compares Acc with zero
        sjmp    test1_dptrm

$errm1: sjmp   $errm1           ;the DPH is not zero after reset
$errm2:	sjmp   $errm2           ;the DPL is not zero after reset
$errm3:	sjmp   $errm3           ;the DPH1 is not zero after reset
$errm4: sjmp   $errm4           ;the DPL1 is not zero after reset
	;--------------------------------------------------------------
	;                        INC DPTR TEST
	;--------------------------------------------------------------
test1_dptrm:
        inc	dptr		;increment the Data Pointer
	mov	a,dpl           ;the Acc loads the contents of the DPL
	cjne    a,#01,$errm5    ;compares Acc with 1
	mov	a,dph		;the Acc loads the contents of the DPH
	cjne	a,#0,$errm6     ;compares Acc with 0
	mov	a,dph1          ;the Acc loads the contents of the DPH1
	cjne    a,#0,$errm7     ;compares Acc with zero
	mov	a,dpl1          ;the Acc loads the contents of the DPL1
	cjne    a,#0,$errm8     ;compares Acc with zero
	mov	dpl,#ffh        ;The DPL loads FFH
	inc	dptr            ;increment the Data Pointer
        mov	a,dpl           ;the Acc loads the contents of the DPL
	cjne    a,#0,$errm9     ;compares Acc with 0
	mov	a,dph		;the Acc loads the contents of the DPH
	cjne	a,#1,$errm10    ;compares Acc with 1
	mov	a,dph1          ;the Acc loads the contents of the DPH1
	cjne    a,#0,$errm11    ;compares Acc with zero
	mov	a,dpl1          ;the Acc loads the contents of the DPL1
	cjne    a,#0,$errm12    ;compares Acc with zero
	mov	dpl,#0          ;clear the DPL
	mov     dph,#0          ;clear the DPH
	mov	eo,#1           ;select the DPTR1 data pointer
	inc	dptr            ;increment DPTR1
	mov	a,dph1          ;load Acc with DPH1
	cjne    a,#0,$errm13    ;compare with zero
	mov     a,dpl1          ;load Acc with DPL1
	cjne    a,#01,$errm14   ;compare with one
	mov	eo,#0           ;select DPTR register
	mov     a,dph           ;load Acc with DPH
	cjne    a,#0,$errm15    ;compare with zero
	mov     a,dpl           ;load Acc with DPL
	cjne    a,#0,$errm16    ;compare with zero
	mov     eo,#1           ;select DPTR1 register
	mov     dpl1,#ffh       ;load DPL1 with FFH
	mov     dph1,#0         ;load DPH1 with zero
	inc     dptr            ;increment DPTR1
	mov     a,dph1          ;load Acc with DPH1
	cjne    a,#01,$errm17   ;compare with one
	mov     a,dpl1          ;load Acc with DPL1
	cjne    a,#0,$errm18    ;compare with zero
	mov     eo,#0           ;select the DPTR register
	mov     a,dph           ;load Acc with DPH
	cjne    a,#0,$errm19    ;compare with zero
	mov     a,dpl           ;load Acc with DPL
	cjne    a,#0,$errm20    ;compare with  zero
        sjmp    test2_dptrm

$errm5:	sjmp	$errm5		;the DPL is not 1 after INC from reset
$errm6: sjmp	$errm6          ;the DPH is not zero
$errm7: sjmp    $errm7          ;the DPH1 is not zero after reset
$errm8:	sjmp    $errm8		;the DPL1 is not zero after reset
$errm9: sjmp    $errm9          ;the DPL is not zero
$errm10:sjmp    $errm10         ;the DPH is not 1
$errm11:sjmp    $errm11         ;the DPH1 is not zero after reset
$errm12:sjmp    $errm12         ;the DPL1 is not zero after reset
$errm13:sjmp    $errm13         ;the DPH1 is not zero
$errm14:sjmp    $errm14         ;the DPL1 is not one
$errm15:sjmp    $errm15         ;the DPH is not zero
$errm16:sjmp    $errm16         ;the DPL is not zero
$errm17:sjmp    $errm17         ;the DPH1 is not one after INC
$errm18:sjmp    $errm18         ;the DPL1 is not zero after INC
$errm19:sjmp    $errm19         ;the dph is not zero
$errm20:sjmp    $errm20         ;the dpl is not zero
	;---------------------------------------------------------------
	;                      MOV DPTR, #DATA TEST
	;---------------------------------------------------------------
test2_dptrm:
        call	init_dptrm      ;initialize the DPTR, DPTR1 registers
	mov	dptr,#20h       ;loads the DPTR with 20h
	mov	a,dph           ;loads the contents of the DPH to Acc
	cjne    a,#0,$errm21    ;compares with zero
	mov	a,dpl		;loads the contents of the DPL to Acc
	cjne	a,#20h,$errm22  ;compares with 20h
	mov     eo,#1           ;select DPTR1
	mov	a,dph1		;loads the contents of the DPH1 to Acc
	cjne    a,#0,$errm23    ;compares with zero
	mov	a,dpl1		;loads the contents of the DPL1 to Acc
	cjne    a,#0,$errm24    ;compares with zero
	mov     eo,#0           ;select DPTR register
	mov     DPTR,#200h      ;load DPTR with 200h
	mov     a,dph           ;load Acc with DPH
	cjne    a,#02h,$errm25  ;compare with 02h
	mov     a,dpl           ;load Acc with DPL
	cjne    a,#0,$errm26    ;compare with zero
	mov     eo,#01          ;select the DPTR1 register
	mov     a,dph1          ;load Acc with DPH1 
	cjne    a,#0,$errm27    ;compare with zero
	mov     a,dpl1          ;load Acc with DPL1
	cjne    a,#0,$errm28    ;compare with zero
        call    init_dptrm      ;initialize the DPTR, DPTR1 registers
	mov     eo,#01          ;select the DPTR1 register
	mov     dptr,#10h       ;load DPTR1 with 10h
	mov     a,dph1          ;load Acc with DPH1
	cjne    a,#0,$errm29    ;compare with zero
	mov     a,dpl1          ;load Acc with DPL1
	cjne    a,#10h,$errm30  ;compare with 10h
	mov     eo,#0           ;select DPTR
	mov     a,dph           ;load Acc with DPH
	cjne    a,#0,$errm31    ;compare with 0
	mov     a,dpl           ;load Acc with DPL
	cjne    a,#0,$errm32    ;compare with zero
	mov     eo,#01          ;select DPTR1 register
	mov     dptr,#0100h     ;load DPTR1 with 100h
	mov     a,dph1          ;load Acc with DPH1
	cjne    a,#01h,$errm33  ;compare with 01
	mov     a,dpl1          ;load Acc with DPL1
	cjne    a,#0,$errm34    ;compare with zero
	mov     eo,#0           ;select DPTR register
	mov     a,dph           ;load Acc with DPH
	cjne    a,#0,$errm35    ;compare with zero  
	mov     a,dpl           ;load Acc with DPL
	cjne    a,#0,$errm36    ;compare with zero      
        sjmp	test3_dptrm

$errm21:sjmp	$errm21         ;the DPH is not zero
$errm22:sjmp    $errm22         ;the DPL is not 20H
$errm23:sjmp	$errm23     	;the DPH1 is not zero
$errm24:sjmp	$errm24     	;the DPL1 is not zero
$errm25:sjmp    $errm25         ;the DPH is not 02h
$errm26:sjmp    $errm26         ;the DPL is not zero
$errm27:sjmp    $errm27         ;the DPH1 is not zero
$errm28:sjmp    $errm28         ;the DPL1 is not zero
$errm29:sjmp    $errm29         ;the DPH1 is not zero
$errm30:sjmp    $errm30         ;the DPL1 is not 10h
$errm31:sjmp    $errm31         ;the DPH is not zero
$errm32:sjmp    $errm32         ;the DPL is not zero
$errm33:sjmp    $errm33         ;the DPH1 is not one
$errm34:sjmp    $errm34         ;the DPL1 is not zero
$errm35:sjmp    $errm35         ;the DPH is not zero
$errm36:sjmp    $errm36         ;the DPL is not zero
        ;----------------------------------------------------------------
	;                     MOVC A,@A+DPTR TEST
	;----------------------------------------------------------------
test3_dptrm:
	call    init_dptrm      ;initialize DPTR, DPTR1 registers
        mov	a,#02h		;loads the Acc with 2
	mov	DPTR,#db_tbl    ;loads the DPTR with the address of db_tbl
	mov     eo,#1           ;select DPTR1 register
	mov     dptr,#3040h     ;load DPTR1 with 3040h
	mov     eo,#0           ;select DPTR register
	movc	a,@a+dptr	;load code byte 
        cjne	a,#02,$errm37   ;compare with 02
	inc	a               ;increment the Acc register
	movc	a,@a+dptr       ;load new code byte
	cjne	a,#04,$errm38   ;compare with 04

	mov     eo,#01          ;select DPTR1
	mov	a,dpl1		;move DPL1 to Acc
	cjne	a,#40h,$errm39  ;compare with 40h
	mov	a,dph1		;move DPH1 to Acc
	cjne	a,#30h,$errm40  ;compare with 30h 
	call    init_dptrm      ;initialize DPTR, DPTR1 registers
	mov     eo,#01          ;select DPTR1 register
	mov     dptr,#db_tbl    ;loads the DPTR with the address of db_tbl
	mov     a,#5            ;load Acc with 5
	mov     eo,#0           ;select the DPTR register
	mov     dptr,#1020h     ;load DPTR with 1020h
	mov     eo,#01          ;select the DPTR1 register
	movc	a,@a+dptr       ;load new code byte
        cjne    a,#08h,$errm41  ;compare with 08
	mov     eo,#0           ;select DPTR register
	mov     a,dph           ;load Acc with DPH
	cjne    a,#10h,$errm42  ;compare with 10h
        mov     a,dpl           ;load Acc with DPL
	cjne    a,#20h,$errm43  ;compare with 20h
	sjmp    test4_dptrm

$errm37:sjmp	$errm37         ;the Acc is not 2
$errm38:sjmp	$errm38		;the Acc is not 4
$errm39:sjmp	$errm39		;the Acc is not 40h
$errm40:sjmp	$errm40         ;the Acc is not 30h
$errm41:sjmp    $errm41         ;the Acc is not 8
$errm42:sjmp    $errm42         ;the Acc is not 10h
$errm43:sjmp    $errm43         ;the Acc is not 20h
db_tbl:	db	00h
	db	01h
	db	02h
	db	04h
	db	06h
	db      08h
	db      10h
	db      12h
	;----------------------------------------------------------------
	;                      JMP @A+DPTR TEST
	;----------------------------------------------------------------
test4_dptrm:
	call	init_dptrm	;initialize DPTR, DPTR1 registers
	mov	a,#02		;load 2 to Acc register
	mov	dptr,#jmp_tbl   ;load jmp_tbl address to DPTR
	mov     eo,#01          ;select DPTR1 register
	mov	dptr,#1020h     ;load DPTR1 with 1020h
	mov     eo,#0           ;select  DPTR register
	jmp	@a+dptr		;jump to a specific location	      
test5:  jmp	@a+dptr         ;jump to a specific location
test6:  cjne	a,#6h,errm44    ;compare with 6
	mov     eo,#01          ;select DPTR1 register
	mov	a,dpl1		;move DPL1 to Acc
	cjne	a,#20h,errm45   ;compare with 20h
	mov	a,dph1		;move DPH1 to Acc
	cjne	a,#10h,errm46   ;compare with 10h 
	mov     eo,#0           ;select DPTR register
	mov     dptr,#2010h     ;load DPTR with 2010h
	mov     eo,#01          ;select DPTR1 register
	mov     a,#06           ;load Acc with 6
	mov     dptr,#jmp_tbl   ;load jmp_tbl address to DPTR
	jmp     @a+dptr         ;jump to a specific location
test7:  cjne    a,#08,errm47    ;compare with 08
	mov     eo,#0           ;select DPTR register
	mov     a,dph           ;load Acc with DPH
	cjne    a,#20h,errm48   ;compare with 20h
	mov     a,dpl           ;load Acc with DPL
	cjne    a,#10h,errm49   ;compare with 10h
	sjmp    test8_dptrm
	
errm44:	sjmp	errm44          ;the Acc is not 6
errm45: sjmp	errm45	        ;the Acc is not 20h
errm46:	sjmp	errm46          ;the Acc is not 10h
errm47: sjmp    errm47          ;the Acc is not 8
errm48: sjmp    errm48          ;the Acc is not 20h
errm49: sjmp    errm49          ;the Acc is not 10h

jmp_tbl:ajmp	jmp0
	ajmp    jmp2
	ajmp	jmp4
	ajmp    jmp6	

jmp0:	mov	a,#02		;move 1 to Acc
	jmp	test5
jmp2:	mov	a,#04		;move 4 to Acc
	jmp	test5
jmp4:	mov	a,#06		;move 6 to Acc
	jmp	test6
jmp6:   mov     a,#08           ;move 8 to Acc
	jmp     test7
	;----------------------------------------------------------------
	;                MOVX A,@DPTR - MOVX @DPTR,A TEST
	;----------------------------------------------------------------
test8_dptrm:
	call	init_dptrm	;initialize the Data Pointers
	mov	dptr,#20h	;move 20h to DPTR	
	mov	a,#15h		;move 15h to Acc
	movx	@dptr,a         ;move Acc to the address of the DPTR
	clr	a		;clear the Acc register
	movx	a,@dptr         ;move the @dptr to Acc
	cjne	a,#15h,$errm50  ;compare Acc with 15h
	mov	a,dph           ;move DPH to Acc
	cjne    a,#0,$errm51    ;compare Acc with zero
	mov	a,dpl           ;move DPL to Acc
	cjne    a,#20h,$errm52  ;compare Acc with 20h
	mov     eo,#1           ;select DPTR1 register
	mov	a,dph1          ;move DPH1 to Acc
	cjne	a,#0,$errm53    ;compare Acc with zero
	mov 	a,dpl1          ;move DPL1 to Acc
	cjne    a,#0,$errm54    ;compare Acc with 30h
	call    init_dptrm      ;initialize the Data pointers
	mov     eo,#01          ;select DPTR1 register
	mov     a,#20h          ;load Acc with 20h
	mov     dptr,#30h       ;load dptr with 30h
	movx    @dptr,a         ;move Acc to the address of the DPTR
	clr     a               ;clear Acc
	movx    a,@dptr         ;move the @DPTR to Acc
	cjne    a,#20h,$errm55  ;compare with 20h
	mov     a,dph1          ;load Acc with DPH1
	cjne    a,#0,$errm56    ;compare with zero 
	mov     a,dpl1          ;load Acc with DPL1
	cjne    a,#30h,$errm57  ;compare with 30h
	mov     eo,#0           ;select the DPTR register
	mov     a,dph           ;load Acc with DPH
	cjne    a,#0,$errm58    ;compare with 0
	mov     a,dpl           ;load Acc with DPL
	cjne    a,#0,$errm59    ;compare with zero
	jmp	dptrb_tst       ;if the program reaches that point there are 
                                ;no errors

$errm50:sjmp	$errm50		;the Acc is not 15h
$errm51:sjmp	$errm51         ;the Acc is not zero
$errm52:sjmp    $errm52         ;the Acc is not 20h
$errm53:sjmp    $errm53         ;the Acc is not zero
$errm54:sjmp    $errm54         ;the Acc is not 30h
$errm55:sjmp    $errm55         ;the Acc is not 20h
$errm56:sjmp    $errm56         ;the Acc is not zero
$errm57:sjmp    $errm57         ;the Acc is not 30h
$errm58:sjmp    $errm58         ;the Acc is not zero
$errm59:sjmp    $errm59         ;the Acc is not zero
        ;----------------------------------------------------------------       
init_dptrm:
        mov     eo,#0           ;select DPTR register
        mov	dph,#0		;clear DPH
	mov	dpl,#0		;clear DPL
	mov     eo,#1           ;select DPTR1 register
	mov	dph1,#0		;clear DPH1
	mov	dpl1,#0         ;clear DPL1
	mov     eo,#0           ;select DPTR register
	ret

	;---------------------------------------------------------------------------
	;                          DPTR BANKED TEST
	;---------------------------------------------------------------------------
intsb_tst1:
	jmp	ints_tst		;continue the test
dptrb_tst:
	mov	a,config_reg		;Copy config_reg to Acc
	jb	a.3,intsb_tst1            ;Jump to ints1_tst if Acc.3=1
	jb	a.4,dptrb_tst1          ;Jump to dptrb_tst if Acc.4=1
	jmp	ints_tst		;continue the test
dptrb_tst1:
	jb	a.5,dptrb_tst2          ;Jump to dptrb_tst2 if Acc.5=1
	jmp	ints_tst		;continue the test
dptrb_tst2:
	;-------------------------------------------------------------
	;                     INITIALIZATION TEST
	;-------------------------------------------------------------
        mov	a,eo		;load Acc with EO register
	cjne	a,#0,$errb16    ;compare with zero
	call	dptr_zero	;see if DPTR is zero
	call	dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	sjmp	test1_dptrb     ;goto INC Test

$errb16: sjmp    $errb16        ;the EO register is not zero after reset
        ;--------------------------------------------------------------
	;                                INC TEST
	;--------------------------------------------------------------
        ;------ TEST OF THE DPTR --------------	
test1_dptrb:
        mov	eo,#0		;select the DPTR register
	mov	dph,#0          ;load DPH with 0
	mov     dpl,#ffh        ;load DPL with FFH
	inc	dptr            ;increment DPTR
	mov	r0,#0           ;load the desired value of DPL
	mov     r1,#1           ;load the desired value of DPH
	call    examine_register;examine the DPTR register
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
        ;------ TEST OF THE DPTR1 --------------
        mov	eo,#1		;select the DPTR1 register
	mov	dph,#01          ;load DPH1 with 01
	mov     dpl,#ffh        ;load DPL1 with FFH
	inc	dptr            ;increment DPTR1
	mov	r0,#0           ;load the desired value of DPL1
	mov     r1,#2           ;load the desired value of DPH1
	call    examine_register;examine the DPTR1 register
	call    dptr_zero       ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
        ;------ TEST OF THE DPTR2 --------------
        mov	eo,#2		;select the DPTR2 register
	mov	dph,#02         ;load DPH2 with 02
	mov     dpl,#ffh        ;load DPL2 with FFH
	inc	dptr            ;increment DPTR2
	mov	r0,#0           ;load the desired value of DPL2
	mov     r1,#3           ;load the desired value of DPH2
	call    examine_register;examine the DPTR2 register
	call    dptr_zero       ;see if DPTR is zero
        call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;------ TEST OF THE DPTR3 --------------
        mov	eo,#3		;select the DPTR3 register
	mov	dph,#03         ;load DPH3 with 03
	mov     dpl,#ffh        ;load DPL3 with FFH
	inc	dptr            ;increment DPTR3
	mov	r0,#0           ;load the desired value of DPL3
	mov     r1,#4           ;load the desired value of DPH3
	call    examine_register;examine the DPTR3 register
	call    dptr_zero       ;see if DPTR is zero
        call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;------ TEST OF THE DPTR4 --------------
        mov	eo,#4		;select the DPTR4 register
	mov	dph,#04         ;load DPH4 with 04
	mov     dpl,#ffh        ;load DPL4 with FFH
	inc	dptr            ;increment DPTR4
	mov	r0,#0           ;load the desired value of DPL4
	mov     r1,#5           ;load the desired value of DPH4
	call    examine_register;examine the DPTR4 register
	call    dptr_zero       ;see if DPTR is zero
        call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR3 is zero
	call    dptr3_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
        ;------ TEST OF THE DPTR5 --------------
        mov	eo,#5		;select the DPTR5 register
	mov	dph,#05         ;load DPH5 with 05
	mov     dpl,#ffh        ;load DPL5 with FFH
	inc	dptr            ;increment DPTR5
	mov	r0,#0           ;load the desired value of DPL5
	mov     r1,#6           ;load the desired value of DPH5
	call    examine_register;examine the DPTR5 register
	call    dptr_zero       ;see if DPTR is zero
        call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR3 is zero
	call    dptr3_zero      ;see if DPTR4 is zero
	call    dptr4_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;------ TEST OF THE DPTR6 --------------
        mov	eo,#6		;select the DPTR6 register
	mov	dph,#06         ;load DPH6 with 06
	mov     dpl,#ffh        ;load DPL6 with FFH
	inc	dptr            ;increment DPTR6
	mov	r0,#0           ;load the desired value of DPL6
	mov     r1,#7           ;load the desired value of DPH6
	call    examine_register;examine the DPTR6 register
	call    dptr_zero       ;see if DPTR is zero
        call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR3 is zero
	call    dptr3_zero      ;see if DPTR4 is zero
	call    dptr4_zero      ;see if DPTR5 is zero
	call    dptr5_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb       ;initialize the 8 Data pointers
        ;------ TEST OF THE DPTR7 --------------
        mov	eo,#7		;select the DPTR7 register
	mov	dph,#07         ;load DPH7 with 07
	mov     dpl,#ffh        ;load DPL7 with FFH
	inc	dptr            ;increment DPTR7
	mov	r0,#0           ;load the desired value of DPL7
	mov     r1,#8           ;load the desired value of DPH7
	call    examine_register;examine the DPTR7 register
	call    dptr_zero       ;see if DPTR is zero
        call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR3 is zero
	call    dptr3_zero      ;see if DPTR4 is zero
	call    dptr4_zero      ;see if DPTR5 is zero
	call    dptr5_zero      ;see if DPTR6 is zero
	call    dptr6_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
        ;----------------------------------------
	sjmp    test2_dptrb     ;continue the testing
	;--------------------------------------------------------------
	;                   MOV DPTR, #DATA TEST
	;--------------------------------------------------------------
	;------- TEST OF THE DPTR ----------------
test2_dptrb:
        mov	eo,#0		;select the DPTR register
	mov	dptr,#1020h     ;load the DPTR with 1020h
	mov	r0,#20h         ;load the desired value of DPL
	mov     r1,#10h         ;load the desired value of DPH
	call    examine_register;examine the DPTR register
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;------- TEST OF THE DPTR1 ----------------
	mov	eo,#1		;select the DPTR1 register
	mov	dptr,#2030h     ;load the DPTR1 with 2030h
	mov	r0,#30h         ;load the desired value of DPL1
	mov     r1,#20h         ;load the desired value of DPH1
	call    examine_register;examine the DPTR1 register
	call    dptr_zero       ;see if DPTR is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
        ;------- TEST OF THE DPTR2 ----------------
	mov	eo,#2		;select the DPTR2 register
	mov	dptr,#3040h     ;load the DPTR2 with 3040h
	mov	r0,#40h         ;load the desired value of DPL2
	mov     r1,#30h         ;load the desired value of DPH2
	call    examine_register;examine the DPTR2 register
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;------- TEST OF THE DPTR3 ----------------
	mov	eo,#3		;select the DPTR3 register
	mov	dptr,#4050h     ;load the DPTR3 with 4050h
	mov	r0,#50h         ;load the desired value of DPL3
	mov     r1,#40h         ;load the desired value of DPH3
	call    examine_register;examine the DPTR3 register
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;------- TEST OF THE DPTR4 ----------------
	mov	eo,#4		;select the DPTR4 register
	mov	dptr,#5060h     ;load the DPTR4 with 5060h
	mov	r0,#60h         ;load the desired value of DPL4
	mov     r1,#50h         ;load the desired value of DPH4
	call    examine_register;examine the DPTR4 register
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;------- TEST OF THE DPTR5 ----------------
	mov	eo,#5		;select the DPTR5 register
	mov	dptr,#6070h     ;load the DPTR5 with 6070h
	mov	r0,#70h         ;load the desired value of DPL5
	mov     r1,#60h         ;load the desired value of DPH5
	call    examine_register;examine the DPTR5 register
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;------- TEST OF THE DPTR6 ----------------
	mov	eo,#6		;select the DPTR6 register
	mov	dptr,#7080h     ;load the DPTR6 with 7080h
	mov	r0,#80h         ;load the desired value of DPL6
	mov     r1,#70h         ;load the desired value of DPH6
	call    examine_register;examine the DPTR6 register
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;------- TEST OF THE DPTR7 ----------------
	mov	eo,#7		;select the DPTR7 register
	mov	dptr,#8090h     ;load the DPTR7 with 8090h
	mov	r0,#90h         ;load the desired value of DPL7
	mov     r1,#80h         ;load the desired value of DPH7
	call    examine_register;examine the DPTR7 register
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    init_dptrb      ;initialize the 8 Data pointers
	;-------------------------------------------
	sjmp    test3_dptrb     ;continue the testing
	;-------------------------------------------------------------
	;                MOVC A,@A+DPTR  TEST
	;-------------------------------------------------------------
        ;------- TEST OF THE DPTR ----------------
test3_dptrb:
	mov	eo,#0		;select DPTR register
	mov	a,#0            ;Load Acc with 0
	mov     dptr,#db_tblb   ;load DPTR with db_tbl address
	movc    a,@a+dptr       ;load code byte
	mov	r0,#10h         ;load desired value of Acc
	call    examine_Acc     ;examine contents of Acc
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR1 ----------------
	mov	eo,#1		;select DPTR1 register
	mov	a,#1            ;Load Acc with 1
	mov     dptr,#db_tblb   ;load DPTR1 with db_tbl address
	movc    a,@a+dptr       ;load code byte
	mov	r0,#11h         ;load desired value of Acc
	call    examine_Acc     ;examine contents of Acc
	call    dptr_zero       ;see if DPTR is zero	
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR2 ----------------
	mov	eo,#2		;select DPTR2 register
	mov	a,#2            ;Load Acc with 2
	mov     dptr,#db_tblb   ;load DPTR with db_tbl address
	movc    a,@a+dptr       ;load code byte
	mov	r0,#12h         ;load desired value of Acc
	call    examine_Acc     ;examine contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR3 ----------------
	mov	eo,#3		;select DPTR3 register
	mov	a,#3            ;Load Acc with 3
	mov     dptr,#db_tblb   ;load DPTR with db_tbl address
	movc    a,@a+dptr       ;load code byte
	mov	r0,#13h         ;load desired value of Acc
	call    examine_Acc     ;examine contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR4 ----------------
	mov	eo,#4		;select DPTR4 register
	mov	a,#4            ;Load Acc with 4
	mov     dptr,#db_tblb   ;load DPTR with db_tbl address
	movc    a,@a+dptr       ;load code byte
	mov	r0,#14h         ;load desired value of Acc
	call    examine_Acc     ;examine contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR5 ----------------
	mov	eo,#5		;select DPTR5 register
	mov	a,#5            ;Load Acc with 5
	mov     dptr,#db_tblb   ;load DPTR with db_tbl address
	movc    a,@a+dptr       ;load code byte
	mov	r0,#15h         ;load desired value of Acc
	call    examine_Acc     ;examine contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR6 ----------------
	mov	eo,#6		;select DPTR6 register
	mov	a,#6            ;Load Acc with 6
	mov     dptr,#db_tblb   ;load DPTR with db_tbl address
	movc    a,@a+dptr       ;load code byte
	mov	r0,#16h         ;load desired value of Acc
	call    examine_Acc     ;examine contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR7 ----------------
	mov	eo,#7		;select DPTR7 register
	mov	a,#7            ;Load Acc with 7
	mov     dptr,#db_tblb   ;load DPTR with db_tbl address
	movc    a,@a+dptr       ;load code byte
	mov	r0,#17h         ;load desired value of Acc
	call    examine_Acc     ;examine contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	sjmp    test4_dptrb     ;continue the testing
	;------------------------------------------
db_tblb:
	db	10h
	db      11h
	db	12h
	db	13h
	db      14h
	db	15h
	db      16h
        db      17h
	db      18h
	db      19h
	db      1ah
	db      1bh
	db      1ch
	db      1dh
	db      1eh
	db      1fh
	;--------------------------------------------------------------
	;                       JMP    @A+DPTR TEST
	;--------------------------------------------------------------
	;------- TEST OF THE DPTR ----------------
test4_dptrb:
	mov	eo,#0		;select the DPTR register
	mov	dptr,#jmp_tblb	;load DPTR with jmp_tbl address
	mov	a,#0		;load Acc with 0
	jmp	@a+dptr         ;jump to a specific location
tst0b:  mov     r0,#20h         ;load desired value of Acc
	call    examine_Acc     ;examine the contents of Acc
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR1 ----------------
	mov	eo,#1		;select the DPTR1 register
	mov	dptr,#jmp_tblb	;load DPTR with jmp_tbl address
	mov	a,#2		;load Acc with 2
	jmp	@a+dptr         ;jump to a specific location
tst1b:  mov     r0,#21h          ;load desired value of Acc
	call    examine_Acc     ;examine the contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR2 ----------------
	mov	eo,#2		;select the DPTR2 register
	mov	dptr,#jmp_tblb	;load DPTR with jmp_tbl address
	mov	a,#4		;load Acc with 4
	jmp	@a+dptr         ;jump to a specific location
tst2b:  mov     r0,#22h          ;load desired value of Acc
	call    examine_Acc     ;examine the contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR3 ----------------
	mov	eo,#3		;select the DPTR3 register
	mov	dptr,#jmp_tblb	;load DPTR with jmp_tbl address
	mov	a,#6		;load Acc with 6
	jmp	@a+dptr         ;jump to a specific location
tst3b:  mov     r0,#23h          ;load desired value of Acc
	call    examine_Acc     ;examine the contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR4 ----------------
	mov	eo,#4		;select the DPTR4 register
	mov	dptr,#jmp_tblb	;load DPTR with jmp_tbl address
	mov	a,#8		;load Acc with 8
	jmp	@a+dptr         ;jump to a specific location
tst4b:  mov     r0,#24h          ;load desired value of Acc
	call    examine_Acc     ;examine the contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR5 ----------------
	mov	eo,#5		;select the DPTR5 register
	mov	dptr,#jmp_tblb	;load DPTR with jmp_tbl address
	mov	a,#10		;load Acc with 10
	jmp	@a+dptr         ;jump to a specific location
tst5b:  mov     r0,#25h          ;load desired value of Acc
	call    examine_Acc     ;examine the contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR6 ----------------
	mov	eo,#6		;select the DPTR6 register
	mov	dptr,#jmp_tblb	;load DPTR with jmp_tbl address
	mov	a,#12		;load Acc with 12
	jmp	@a+dptr         ;jump to a specific location
tst6b:  mov     r0,#26h          ;load desired value of Acc
	call    examine_Acc     ;examine the contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR7 ----------------
	mov	eo,#7		;select the DPTR7 register
	mov	dptr,#jmp_tblb	;load DPTR with jmp_tbl address
	mov	a,#14		;load Acc with 14
	jmp	@a+dptr         ;jump to a specific location
tst7b:  mov     r0,#27h          ;load desired value of Acc
	call    examine_Acc     ;examine the contents of Acc
	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	sjmp	test5_dptrb     ;continue the testing
        ;------------------------------------------
jmp_tblb:
        ajmp	jmpb0
	ajmp	jmpb1
	ajmp	jmpb2
	ajmp	jmpb3
	ajmp	jmpb4
	ajmp	jmpb5
	ajmp	jmpb6
	ajmp	jmpb7

jmpb0:	mov	a,#20h
	jmp	tst0b

jmpb1:	mov	a,#21h
	jmp	tst1b

jmpb2:	mov	a,#22h
	jmp	tst2b

jmpb3:	mov	a,#23h
	jmp	tst3b

jmpb4:	mov	a,#24h
	jmp	tst4b

jmpb5:	mov	a,#25h
	jmp	tst5b

jmpb6:	mov	a,#26h
	jmp	tst6b

jmpb7:	mov	a,#27h
	jmp	tst7b
	;--------------------------------------------------------------
	;              MOVX A,@DPTR - MOVX @DPTR,A TEST
	;--------------------------------------------------------------
	;------- TEST OF THE DPTR ----------------
test5_dptrb:
	mov	eo,#0		;select DPTR register
	mov	dptr,#30h       ;load DPTR with  30h
	mov	a,#20h          ;load Acc with 20h
	movx    @dptr,a         ;move Acc to the address of the DPTR
	clr	a		;clear the Acc
	movx    a,@dptr         ;move the @dptr to Acc
	mov	r0,#20h         ;load R0 with the desired value of Acc
	call    examine_Acc     ;examine the contents of the Acc
 	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR1 ----------------
	mov	eo,#1		;select DPTR1 register
	mov	dptr,#31h       ;load DPTR with  31h
	mov	a,#21h          ;load Acc with 21h
	movx    @dptr,a         ;move Acc to the address of the DPTR1
	clr	a		;clear the Acc
	movx    a,@dptr         ;move the @dptr to Acc
	mov	r0,#21h         ;load R0 with the desired value of Acc
	call    examine_Acc     ;examine the contents of the Acc
 	call    dptr_zero       ;see if DPTR is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR2 ----------------
	mov	eo,#2		;select DPTR2 register
	mov	dptr,#32h       ;load DPTR with  32h
	mov	a,#22h          ;load Acc with 22h
	movx    @dptr,a         ;move Acc to the address of the DPTR2
	clr	a		;clear the Acc
	movx    a,@dptr         ;move the @dptr to Acc
	mov	r0,#22h         ;load R0 with the desired value of Acc
	call    examine_Acc     ;examine the contents of the Acc
 	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR3 ----------------
	mov	eo,#3		;select DPTR3 register
	mov	dptr,#33h       ;load DPTR with  33h
	mov	a,#23h          ;load Acc with 23h
	movx    @dptr,a         ;move Acc to the address of the DPTR3
	clr	a		;clear the Acc
	movx    a,@dptr         ;move the @dptr to Acc
	mov	r0,#23h         ;load R0 with the desired value of Acc
	call    examine_Acc     ;examine the contents of the Acc
 	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR4 ----------------
	mov	eo,#4		;select DPTR4 register
	mov	dptr,#34h       ;load DPTR with  34h
	mov	a,#24h          ;load Acc with 24h
	movx    @dptr,a         ;move Acc to the address of the DPTR4
	clr	a		;clear the Acc
	movx    a,@dptr         ;move the @dptr to Acc
	mov	r0,#24h         ;load R0 with the desired value of Acc
	call    examine_Acc     ;examine the contents of the Acc
 	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR5 ----------------
	mov	eo,#5		;select DPTR5 register
	mov	dptr,#35h       ;load DPTR with  35h
	mov	a,#25h          ;load Acc with 25h
	movx    @dptr,a         ;move Acc to the address of the DPTR5
	clr	a		;clear the Acc
	movx    a,@dptr         ;move the @dptr to Acc
	mov	r0,#25h         ;load R0 with the desired value of Acc
	call    examine_Acc     ;examine the contents of the Acc
 	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR6 ----------------
	mov	eo,#6		;select DPTR6 register
	mov	dptr,#36h       ;load DPTR with  36h
	mov	a,#26h          ;load Acc with 26h
	movx    @dptr,a         ;move Acc to the address of the DPTR6
	clr	a		;clear the Acc
	movx    a,@dptr         ;move the @dptr to Acc
	mov	r0,#26h         ;load R0 with the desired value of Acc
	call    examine_Acc     ;examine the contents of the Acc
 	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr7_zero      ;see if DPTR7 is zero
	call    init_dptrb      ;initialize the 8 Data Pointers
	;------- TEST OF THE DPTR7 ----------------
	mov	eo,#7		;select DPTR7 register
	mov	dptr,#37h       ;load DPTR with  37h
	mov	a,#27h          ;load Acc with 27h
	movx    @dptr,a         ;move Acc to the address of the DPTR7
	clr	a		;clear the Acc
	movx    a,@dptr         ;move the @dptr to Acc
	mov	r0,#27h         ;load R0 with the desired value of Acc
	call    examine_Acc     ;examine the contents of the Acc
 	call    dptr_zero       ;see if DPTR is zero
	call    dptr1_zero      ;see if DPTR1 is zero
	call    dptr2_zero      ;see if DPTR2 is zero
	call    dptr3_zero      ;see if DPTR3 is zero
	call    dptr4_zero      ;see if DPTR4 is zero
	call    dptr5_zero      ;see if DPTR5 is zero
	call    dptr6_zero      ;see if DPTR6 is zero
	jmp	ints_tst        ;the test has been successfully completed
	;--------------------------------------------------------------
init_dptrb:
	mov	eo,#0		;select the DPTR register
	mov	dptr,#0         ;clear the DPTR register
	mov     eo,#1           ;select the DPTR1 register
	mov	dptr,#0		;clear the DPTR1 register
	mov	eo,#2		;select the DPTR2 register
	mov 	dptr,#0		;clear the DPTR2 register
	mov	eo,#3		;select the DPTR3 register
	mov	dptr,#0		;clear the DPTR3 register
	mov	eo,#4		;select the DPTR4 register
	mov	dptr,#0		;clear the DPTR4 register
	mov	eo,#5		;select the DPTR5 register
	mov	dptr,#0		;clear the DPTR5 register
	mov	eo,#6		;select the DPTR6 register
	mov	dptr,#0		;clear the DPTR6 register
	mov	eo,#7		;select the DPTR7 register
	mov	dptr,#0		;clear the DPTR7 register
	mov	eo,#0		;select the DPTR register
	ret			;return to the main programme
	;--------------------------------------------------------------
dptr_zero:
	mov	eo,#0		;select the DPTR register
	mov	a,dph		;load Acc with DPH
	cjne	a,#0,$errb0     ;compare with zero
	mov	a,dpl		;load Acc with DPL
	cjne	a,#0,$errb1     ;compare with zero
	ret

$errb0:sjmp	$errb0		;the DPH is not zero
$errb1:sjmp	$errb1          ;the DPL is not zero
	;--------------------------------------------------------------
dptr1_zero:
	mov	eo,#1		;select the DPTR1 register
	mov	a,dph		;load Acc with DPH1
	cjne	a,#0,$errb2     ;compare with zero
	mov	a,dpl		;load Acc with DPL1
	cjne	a,#0,$errb3     ;compare with zero
	ret

$errb2:	sjmp	$errb2		;the DPH1 is not zero
$errb3: sjmp	$errb3          ;the DPL1 is not zero
	;--------------------------------------------------------------
dptr2_zero:
	mov	eo,#2		;select the DPTR2 register
	mov	a,dph		;load Acc with DPH2
	cjne	a,#0,$errb4     ;compare with zero
	mov	a,dpl		;load Acc with DPL2
	cjne	a,#0,$errb5     ;compare with zero
	ret

$errb4:	sjmp	$errb4		;the DPH2 is not zero
$errb5: sjmp	$errb5           ;the DPL2 is not zero
;--------------------------------------------------------------
dptr3_zero:
	mov	eo,#3		;select the DPTR3 register
	mov	a,dph		;load Acc with DPH3
	cjne	a,#0,$errb6     ;compare with zero
	mov	a,dpl		;load Acc with DPL3
	cjne	a,#0,$errb7     ;compare with zero
	ret

$errb6:	sjmp	$errb6		;the DPH3 is not zero
$errb7:  sjmp	$errb7          ;the DPL3 is not zero
;--------------------------------------------------------------
dptr4_zero:
	mov	eo,#4		;select the DPTR4 register
	mov	a,dph		;load Acc with DPH4
	cjne	a,#0,$errb8     ;compare with zero
	mov	a,dpl		;load Acc with DPL4
	cjne	a,#0,$errb9     ;compare with zero
	ret

$errb8:	sjmp	$errb8		;the DPH4 is not zero
$errb9: sjmp	$errb9          ;the DPL4 is not zero
;--------------------------------------------------------------
dptr5_zero:
	mov	eo,#5		;select the DPTR5 register
	mov	a,dph		;load Acc with DPH5
	cjne	a,#0,$errb10    ;compare with zero
	mov	a,dpl		;load Acc with DPL5
	cjne	a,#0,$errb11    ;compare with zero
	ret

$errb10:sjmp	$errb10		;the DPH5 is not zero
$errb11:sjmp	$errb11         ;the DPL5 is not zero
;--------------------------------------------------------------
dptr6_zero:
	mov	eo,#6		;select the DPTR6 register
	mov	a,dph		;load Acc with DPH6
	cjne	a,#0,$errb12    ;compare with zero
	mov	a,dpl		;load Acc with DPL6
	cjne	a,#0,$errb13    ;compare with zero
	ret

$errb12:sjmp	$errb12		;the DPH6 is not zero
$errb13:sjmp	$errb13         ;the DPL6 is not zero
;--------------------------------------------------------------
dptr7_zero:
	mov	eo,#7		;select the DPTR7 register
	mov	a,dph		;load Acc with DPH7
	cjne	a,#0,$errbt12    ;compare with zero
	mov	a,dpl		;load Acc with DPL7
	cjne	a,#0,$errbt13    ;compare with zero
	ret

$errbt12:sjmp	$errbt12		;the DPH7 is not zero
$errbt13:sjmp	$errbt13         ;the DPL7 is not zero
        ;--------------------------------------------------------------
examine_register:
	; this routine examines the contents of the current data pointer
	;and compares its value with a desired value supplied through
	;the R0,R1 registers. The data structure for calling this routine
	;has as follows:	
	;*       R0 <- Defines the value to be compared with DPL
	;*       R1 <- Defines the value to be compared with DPH
	mov	a,r0            ;load Acc with R0 
	cjne    a,82h,$errb14   ;compare R0 with DPL
	mov     a,r1            ;load Acc with R0
	cjne    a,83h,$errb15   ;compare R1 with DPH
	ret			;return to the main programme

$errb14:sjmp 	$errb14          ;the DPLx is not equal with a desired value
$errb15:sjmp    $errb15          ;the DPHx is not equal with a desired value
	;--------------------------------------------------------------
examine_Acc:
	;this routine examines the contents of the Accumulator and if its
	;value is different than the value of R0 register the routine
	;goes into an error loop
	cjne	a,00h,$errb17   ;Comapre Acc with R0
	ret			;return to the main programme

$errb17: sjmp	$errb17         ;the Acc is not equal with a desired value

	;---------------------------------------------------------------------------
	;                EXTRA INTERRUPTS EXTRA PRIORITY TEST
	;---------------------------------------------------------------------------
ints_tst:
	mov	a,config_reg		;Copy config_reg to Acc
	jb      a.0,lcall_tst           ;jump to lcalltest if no uart is present
	jb      a.1,lcall_tst           ;jump to lcalltest if no timers are present
	jb	a.6,ints_tst1           ;Jump to ints_tst1 if Acc.6=1
	jmp	ints1_tst		;continue the test
ints_tst1:
	jb	a.7,ints_tst2           ;jump to ints_tst2 if Acc.7=1
	jmp	ints1_tst		;continue the test
lcall_tst:jmp	lcalltest		;continue the test
ints_tst2:
;initialize the interrupt enable registers
;
; check extension external interrupt registers
;
$rst21:	mov	a, ie1 			; address of IE1 register
	jz	$rst22			; ok
	error	E_rst_ie1_notzero	; failed if IE1 is not zero
;
$rst22:	mov	a, ip1	 		; address of IP1 register
	jz	$rst23			; ok
	error	E_rst_ip1_notzero	; failed if IP1 is not zero
	
$rst23: mov	a, iph			; address of IPH register
	jz	rst24			; ok
Err_rst:sjmp	Err_rst                 ; failed if IPH is not zero

rst24:	mov	a, iph1                 ; address of IPH1 register
	jz      rst25                   ; ok
Err_rst1:sjmp   Err_rst1                ; failed if IPH1 is not zero
;
; exercise the port SFRs using a RMW instruction and read port pins
;

rst25:	clr     b.0                     ;clear the global bit B.0 so that the
					;interrupt service routines do not
					;trigger all the interrupts simoultaneously
	clr	a			;clear the Acc register
	mov	ie,a                    ;disable all interrupts
	mov	ie1,a                   ;disable extra external interrupts
	mov	a,#50                   ;start new stack from 50h
	mov     sp,a                    ;initialise stack pointer
	
;ensure timer0 and timer1 are stopped

	orl     p3,#ffh                 ;allow time to see action
	orl     tcon,#50h
	mov     scon,#0                 ;disable the serial interface
	mov     a,#33h
	mov     tmod,a                  ;initialize TMOD
	clr     a                       ;clear the Acc register
	mov	tl0,a			;initialize low byte
	mov     th0,a                   ;initialize high byte
	mov     tl1,a                   ;initialize low byte
	mov     th1,a                   ;initialize high byte
	mov     tcon,#(tcext1control+tcext0control)
	mov     xintr0,a               ;initialize external interrupt sources
	mov     xintr1,a               ;initialize external interrupt sources

;initialize all  interrupt flags
	mov     r1,#i0_int_flag         ;move int flag of ie0
	mov     @r1,#0                  ;clear the ie0 int flag
	mov     r1,#t0_int_flag         ;move int flag of timer0
	mov     @r1,#0                  ;clear the timer0 int flag
	mov     r1,#i1_int_flag         ;move int flag of ie1
	mov	@r1,#0                  ;clear the ie1 int flag
	mov     r1,#t1_int_flag         ;move the timer1 int flag
	mov     @r1,#0                  ;clear the timer1 int flag
	mov     r1,#tr_int_flag         ;move serial int flag
	mov     @r1,#0                  ;clear the serial int flag
	mov     r1,#ext05_int_flag      ;move ie5 int flag
	mov     @r1,#0                  ;clear ie5 int flag
	mov     r1,#ext06_int_flag      ;move ie6 int flag
	mov     @r1,#0                  ;clear ie6 int flag
	mov     r1,#ext07_int_flag      ;move ie7 int flag
	mov     @r1,#0                  ;clear ie7 int flag
	mov     r1,#ext08_int_flag      ;move ie8 int flag
	mov     @r1,#0                  ;clear ie8 int flag
	mov     r1,#ext09_int_flag      ;move ie9 int flag
	mov     @r1,#0                  ;clear ie9 int flag
	mov     r1,#ext10_int_flag      ;move ie10 int flag
	mov     @r1,#0                  ;clear ie10 int flag
	mov     r1,#ext11_int_flag      ;move ie11 int flag
	mov     @r1,#0                  ;clear ie11 int flag
	mov     r1,#ext12_int_flag      ;move ie12 int flag
	mov     @r1,#0                  ;clear ie12 int flag
	mov     r1,#ext13_int_flag      ;move ie13 int flag
	mov     @r1,#0                  ;clear ie13 int flag 

;test each interrupt in succession with higher priority
	mov     r2,#16d                 ;move to r2 the number of test permutations
                                        ;of the priority window
	mov     r0,#int_counter         ;move to R0 the interrupt counter
	mov     @r0,#1                  ;initialize interrupt counter to 1
loopt:  call    update_registerst       ;change the interrupt priorities
                                        ;through the priority window	
;set all interrupt source registers and enable all interrupts
	orl	tcon,#AAh               ;triger ie0,ie1,timer0,timer1 interrupts
	mov     a, config_reg1          ;copy config_reg1 to A
	jb      a.0, tg1                ;continue if timer2 is not included
        setb    tf2                     ;tigger TIMER2 interrupt
tg1:	orl     scon,#03h               ;triger serial interface interrupt
	orl     xintr0,#ffh            ;triger external interrupts through the esfr0
	orl     xintr1,#01h            ;triger external interrupts through the esfr1
	mov     ie1,#ffh                ;enable all interrupt sources
	mov     ie,#bfh                 ;enable all interrupt sources
	mov     p1,r2                   ;allow interrupt to occur make priority under test visible
	clr     ie.7                    ;disable further interrupts
	mov     a, config_reg1          ;copy config_reg1 to A
	jb      a.0,tg2                 ;continue if TIMER2 is disabled
        clr     tf2                     ;do not trigger TIMER2 interrupts	
tg2:	djnz    r2,loopt                 ;loop until all tested
;test all the service times of the interrupts, error test program
	mov     a,ext13_int_flag        ;test the service time of the ie13 interrupt
	cjne    a,#01h,errt8            ;the service time of the ie13 interrupt must be 1
	mov	a,ext12_int_flag        ;test the service time of the ie12 interrupt
	cjne    a,#02h,errt9            ;the service time of the ie12 interrupt must be 2
	mov     a,ext11_int_flag        ;test the service time of the ie11 interrupt
	cjne    a,#03h,errt10           ;the service time of the ie11 interrupt must be 3
        mov	a,ext10_int_flag        ;test the service time of the ie10 interrupt
	cjne    a,#04h,errt11           ;the service time of the ie10 interrupt must be 4
	mov	a,ext09_int_flag        ;test the service time of the ie9 interrupt
	cjne    a,#05h,errt12           ;the service time of the ie9 interrupt must be 5
	mov	a,ext08_int_flag        ;test the service time of the ie8 interrupt
	cjne    a,#06h,errt13           ;the service time of the ie8 interrupt must be 6
	mov     a,ext07_int_flag        ;test the service time of the ie7 interrupt
	cjne    a,#07h,errt14           ;the service time of the ie7 interrupt must be 7
	mov     a,ext06_int_flag        ;test the service time of the ie6 interrupt
	cjne    a,#08h,errt15           ;the service time of the ie6 interrupt must be 8
	mov     a,ext05_int_flag        ;test the service time of the ie5 interrupt
	cjne    a,#09h,errt16           ;the service time of the ie5/TIMER2 interrupt must be 9
	mov     a,tr_int_flag           ;test the service time of the serial interrupt
	cjne    a,#0ah,errt17           ;the service time of the serial interrupt must be 10
	mov     a,t1_int_flag           ;test the service time of the timer1 interrupt
	cjne    a,#0bh,errt18           ;the service time of the timer1 interrupt must be 11
	mov     a,i1_int_flag           ;test the service time of the ie1 interrupt
	cjne    a,#0ch,errt19           ;the service time of the ie1 interrupt must be 12
	mov     a,t0_int_flag           ;test the service time of the timer0 interrupt
	cjne    a,#0dh,errt20           ;the service time of the timer0 interrupt must be 13
	mov     a,i0_int_flag           ;test the service time of the ie0 interrupt
	cjne    a,#10h,errt21           ;the service time of the ie0 interrupt must be 16
	jmp     nmi_testt               ;test the Non-maskable interrupt


errt8:	 sjmp	 errt8                  ;error in the service time of the ie13 interrupt
errt9:   sjmp    errt9                  ;error in the service time of the ie12 interrupt	 
errt10:	 sjmp    errt10	                ;error in the service time of the ie11 interrupt
errt11:  sjmp    errt11                 ;error in the service time of the ie10 interrupt
errt12:  sjmp    errt12                 ;error in the service time of the ie9 interrupt
errt13:  sjmp    errt13                 ;error in the service time of the ie8 interrupt
errt14:  sjmp    errt14                 ;error in the service time of the ie7 interrupt
errt15:  sjmp    errt15                 ;error in the service time of the ie6 interrupt
errt16:  sjmp    errt16                 ;error in the service time of the ie5/TIMER2 interrupt
errt17:  sjmp    errt17                 ;error in the service time of the serial interrupt
errt18:  sjmp    errt18                 ;error in the service time of the timer1 interrupt
errt19:  sjmp    errt19                 ;error in the service time of the ie1 interrupt
errt20:  sjmp    errt20                 ;error in the service time of the timer0 interrupt
errt21:  sjmp    errt21                 ;error in the service time of the ie0 interrupt
	;---------------------------------------------------------------------------------
	;                    Non-Maskable Interrupt  Test
	;---------------------------------------------------------------------------------
nmi_testt:clr    b.0			;clear the global flag B.0 that causes all
					;the interrupt service routines to 
					;trigger all the interrupts simultaneously
	clr	a			;Clear the Acc register
	mov     ie,a			;disable all interrupts
	mov     ie1,a                   ;enable extra external interrupts

;ensure timer0 and timer1 are stopped
	orl	p3,#ffh                 ;allow time to see action
	orl     tcon,#50h               
	mov     scon,#0                 ;disable the serial interface
	mov     a,#33h
	mov     tmod,a                  ;initialize TMOD
	clr     a                       ;clear the Acc register
	mov     tl0,a                   ;initialize low byte
	mov     th0,a                   ;initialize high byte
	mov     tl1,a                   ;initialize low byte
	mov     th1,a                   ;initialize high byte
	mov     tcon,#(tcext1control+tcext0control)
	mov     xintr0,a               ;initialize external interrupt sources
	mov     xintr1,a               ;initialize external interrupt sources

;initialize all  interrupt flags
	mov     r1,#nmi_int_flag        ;move int flag of NMI
	mov     @r1,#0                  ;clear the NMI int flag
	mov     r1,#i0_int_flag         ;move ie0 int flag
	mov     @r1,#0                  ;clear the ie0 int flag 	
	mov	r1,#t0_int_flag          ;move the timer0 int flag
	mov     @r1,#0                  ;clear the timer0 int flag
	mov	r1,#i1_int_flag         ;move the ie1 int flag
	mov     @r1,#0                  ;clear the ie1 int flag
	mov     r1,#t1_int_flag         ;move the timer1 int flag
	mov     @r1,#0                  ;clear the timer1 int flag
	mov     r1,#tr_int_flag         ;move the serial int flag
	mov     @r1,#0                  ;clear the serial int flag
	mov     r1,#ext05_int_flag      ;move the ie5 int flag
	mov     @r1,#0                  ;clear the ie5 int flag
	mov     r1,#ext06_int_flag      ;move the ie6 int flag
	mov     @r1,#0                  ;clear the ie6 int flag
	mov     r1,#ext07_int_flag      ;move the ie7 int flag
	mov     @r1,#0                  ;clear the ie7 int flag
	mov	r1,#ext08_int_flag      ;move the ie8 int flag
	mov     @r1,#0                  ;clear the ie8 int flag
	mov     r1,#ext09_int_flag      ;move the ie9 int flag
	mov     @r1,#0                  ;clear the ie9 int flag
	mov     r1,#ext10_int_flag      ;move the ie10 int flag
	mov     @r1,#0                  ;clear the ie10 int flag
	mov     r1,#ext11_int_flag      ;move the ie11 int flag
	mov     @r1,#0                  ;clear the ie11 int flag
	mov     r1,#ext12_int_flag      ;move the ie12 int flag
	mov     @r1,#0                  ;clear the ie12 int flag
	mov     r1,#ext13_int_flag      ;move the ie13 int flag
	mov     @r1,#0                  ;clear the ie13 int flag

;test each interrupt in succession with higher priority including the NMI
	mov     r2,#16d			;move to R2 the number of test permutations
					;of the priority window
	mov	r0,#int_counter         ;move to R0 the interrupt counter
	mov     @r0,#1                  ;initialize the interrupt counter to 1
	mov     r0,#nmi_counter         ;move to R0 the NMI counter
	mov     @r0,#1                  ;initialize the NMI counter to 1
loop1t: call    update_registerst       ;change the interrupt priorities
					;through the priority window

;set all interrupt sources and enable all interrupts
	orl     tcon,#aah               ;triger ie0,ie1,timer0,timer1 interrupts
	orl     scon,#03                ;triger serial interface interrupt
        mov     A, config_reg1          ;Read config_reg1 register
        jb      A.0,kkj
	setb    tf2                     ;triger timer2 interrupt
kkj:	orl     xintr0,#ffh            ;trigger external interrupts through esfr0
	orl     xintr1,#81h            ;trigger external interrupts plus NMI through esfr1	
	mov     ie1,#ffh                ;enable all interrupt sources
	mov     ie,#bfh                 ;enable all interrupt sources
        mov     p1,r2                   ;allow interrupt to occur make priority under test visible
	clr     ie.7                    ;disable further interrupts
	mov     A, config_reg1          ;Read config_reg1 register
	jb      A.0,k1
	clr     tf2                     ;dont trigger TIMER2 interrupts
k1:	djnz    r2,loop1t               ;loop until all tested

;test all the service times of the interrupts, error test program
	mov     a,nmi_int_flag          ;test the service time of the NMI 
	cjne    a,#16d,errt22           ;the service time of the NMI must be 16
	mov     a,ext13_int_flag        ;test the sevice time of the ie13
	cjne    a,#0,errt23             ;the service time of the ie13 must be 0
	mov     a,ext12_int_flag        ;test the service time of the ie12 flag
	cjne    a,#0,errt24             ;the service time of the ie12 must be 0
	mov     a,ext11_int_flag        ;test the service time of the ie11 flag
	cjne    a,#0,errt25             ;the service time of the ie11 must be 0 
	mov     a,ext10_int_flag        ;test the service time of the ie10 flag
	cjne    a,#0,errt26             ;the service time of the ie10 must be 0
	mov     a,ext09_int_flag        ;test the service time of the ie9 flag
	cjne    a,#0,errt27             ;the service time of the ie9 must be 0
	mov     a,ext08_int_flag        ;test the service time of the ie8 flag
	cjne    a,#0,errt28             ;the service time of the ie8 must be 0
	mov     a,ext07_int_flag        ;test the service time of the ie7 flag
	cjne    a,#0,errt29             ;the service time of the ie7 must be 0
	mov     a,ext06_int_flag        ;test the service time of the ie6 flag
	cjne    a,#0,errt30             ;the service time of the ie6 must be 0
	mov     a,ext05_int_flag        ;test the service time of the ie5 flag
	cjne    a,#0,errt31             ;the service time of the ie5/TIMER2 must be 0
	mov     a,tr_int_flag           ;test the service time of the serial flag
	cjne    a,#0,errt32             ;the service time of the serial must be 0
	mov     a,t1_int_flag           ;test the service time of the timer1 flag
	cjne    a,#0,errt33             ;the service time of the timer1 must be 0
	mov     a,i1_int_flag           ;test the service time of the ie1 flag
	cjne    a,#0,errt34             ;the service time of the ie1 must be 0
	mov     a,t0_int_flag           ;test the service time of the timer0 flag
	cjne    a,#0,errt35             ;the service time of the timer0 must be 0	
	mov     a,i0_int_flag           ;test the service time of the ie0 flag
	cjne    a,#0,errt36             ;the service time of the ie0 must be 0
	jmp	pr_tstt                 ;goto the priority test of the 14 interrupts


errt22: sjmp 	 errt22                 ;error in the service time of the NMI
errt23: sjmp     errt23                 ;error in the service time of the ie13 interrupt
errt24: sjmp     errt24                 ;error in the service time of the ie12 interrupt
errt25: sjmp     errt25                 ;error in the service time of the ie11 interrupt
errt26: sjmp     errt26                 ;error in the service time of the ie10 interrupt
errt27: sjmp     errt27                 ;error in the service time of the ie9 interrupt
errt28: sjmp     errt28                 ;error in the service time of the ie8 interrupt
errt29: sjmp     errt29                 ;error in the service time of the ie7 interrupt
errt30: sjmp     errt30                 ;error in the service time of the ie6 interrupt
errt31: sjmp     errt31                 ;error in the service time of the ie5 interrupt
errt32: sjmp     errt32                 ;error in the service time of the serial interrupt
errt33: sjmp     errt33                 ;error in the service time of the timer1 interrupt
errt34: sjmp     errt34                 ;error in the service time of the ie1 interrupt
errt35: sjmp     errt35                 ;error in the service time of the timer0 interrupt
errt36: sjmp     errt36                 ;error in the service time of the ie0 interrupt
	;------------------------------------------------------------------------
	;             TEST THE 14 MASKABLE INTERRUPTS WITH PRIORITY TEST
	;------------------------------------------------------------------------
pr_tstt:clr    b.0			;clear the global flag B.0 that causes all
					;the interrupt service routines to 
					;trigger all the interrupts simultaneously
	clr	a			;Clear the Acc register
	mov     ie,a			;disable all interrupts
	mov     ie1,a                   ;disable extra external interrupts

;ensure timer0 and timer1 are stopped
	orl	p3,#ffh                 ;allow time to see action
	orl     tcon,#50h               
	mov     scon,#0                 ;disable the serial interface
	mov     a,#33h
	mov     tmod,a                  ;initialize TMOD
	clr     a                       ;clear the Acc register
	mov     tl0,a                   ;initialize low byte
	mov     th0,a                   ;initialize high byte
	mov     tl1,a                   ;initialize low byte
	mov     th1,a                   ;initialize high byte
	mov     tcon,#(tcext1control+tcext0control)
	mov     xintr0,a               ;initialize external interrupt sources
	mov     xintr1,a               ;initialize external interrupt sources

;initialize all  interrupt flags	
	mov     r1,#i0_int_flag         ;move ie0 int flag
	mov     @r1,#0                  ;clear the ie0 int flag 	
	mov	r1,#t0_int_flag         ;move the timer0 int flag
	mov     @r1,#0                  ;clear the timer0 int flag
	mov	r1,#i1_int_flag         ;move the ie1 int flag
	mov     @r1,#0                  ;clear the ie1 int flag
	mov     r1,#t1_int_flag         ;move the timer1 int flag
	mov     @r1,#0                  ;clear the timer1 int flag
	mov     r1,#tr_int_flag         ;move the serial int flag
	mov     @r1,#0                  ;clear the serial int flag
	mov     r1,#ext05_int_flag      ;move the ie5/TIMER2 int flag
	mov     @r1,#0                  ;clear the ie5/TIMER2 int flag
	mov     r1,#ext06_int_flag      ;move the ie6 int flag
	mov     @r1,#0                  ;clear the ie6 int flag
	mov     r1,#ext07_int_flag      ;move the ie7 int flag
	mov     @r1,#0                  ;clear the ie7 int flag
	mov	r1,#ext08_int_flag      ;move the ie8 int flag
	mov     @r1,#0                  ;clear the ie8 int flag
	mov     r1,#ext09_int_flag      ;move the ie9 int flag
	mov     @r1,#0                  ;clear the ie9 int flag
	mov     r1,#ext10_int_flag      ;move the ie10 int flag
	mov     @r1,#0                  ;clear the ie10 int flag
	mov     r1,#ext11_int_flag      ;move the ie11 int flag
	mov     @r1,#0                  ;clear the ie11 int flag
	mov     r1,#ext12_int_flag      ;move the ie12 int flag
	mov     @r1,#0                  ;clear the ie12 int flag
	mov     r1,#ext13_int_flag      ;move the ie13 int flag
	mov     @r1,#0                  ;clear the ie13 int flag

;test each interrupt in succession with higher priority 
	mov     r2,#16d			;move to R2 the number of test permutations
					;of the priority window
	mov	r0,#int_counter         ;move to R0 the interrupt counter
	mov     @r0,#1                  ;initialize the interrupt counter to 1	
loop2t: setb    b.0                     ;enable the global flag B.0 so that each 
					;interrupt service routine will jump to its
					;IRQ subroutine to trigger all the interrupts
					;simoultaneously, therefore a higher priority interrupt
					;will interrupt the current interrupt service routine
					;and hence priority test will take place
	call    update_registerst       ;change the interrupt priorities
					;through the priority window

;trigger all interrupt sources except the interrupt with the highest priority and enable all interrupts
	call    change_priorityt        ;trigger all interrupts except the interrupt with
					;the highest priority (i.e. priority window)
	mov     ie1,#ffh                ;enable all interrupt sources
	mov     ie,#bfh                 ;enable all interrupt sources
        mov     p1,r2                   ;allow interrupt to occur make priority under test visible
	clr     ie.7                    ;disable further interrupts
	djnz    r2,loop2t               ;loop until all tested

;test all the service times of the interrupts, error test program
	
	mov     a,ext13_int_flag        ;test the sevice time of the ie13
	cjne    a,#2d,errt37            ;the service time of the ie13 must be 2
	mov     a,ext12_int_flag        ;test the service time of the ie12 flag
	cjne    a,#4d,errt38            ;the service time of the ie12 must be 4
	mov     a,ext11_int_flag        ;test the service time of the ie11 flag
	cjne    a,#6d,errt39            ;the service time of the ie11 must be 6 
	mov     a,ext10_int_flag        ;test the service time of the ie10 flag
	cjne    a,#8d,errt40            ;the service time of the ie10 must be 8
	mov     a,ext09_int_flag        ;test the service time of the ie9 flag
	cjne    a,#10d,errt41           ;the service time of the ie9 must be 10
	mov     a,ext08_int_flag        ;test the service time of the ie8 flag
	cjne    a,#12d,errt42           ;the service time of the ie8 must be 12
	mov     a,ext07_int_flag        ;test the service time of the ie7 flag
	cjne    a,#14d,errt43           ;the service time of the ie7 must be 14
	mov     a,ext06_int_flag        ;test the service time of the ie6 flag
	cjne    a,#16d,errt44           ;the service time of the ie6 must be 16
	mov     a,ext05_int_flag        ;test the service time of the ie5 flag
	cjne    a,#18d,errt45           ;the service time of the ie5/TIMER2 must be 18
	mov     a,tr_int_flag           ;test the service time of the serial flag
	cjne    a,#20d,errt46           ;the service time of the serial must be 20
	mov     a,t1_int_flag           ;test the service time of the timer1 flag
	cjne    a,#22d,errt47           ;the service time of the timer1 must be 22
	mov     a,i1_int_flag           ;test the service time of the ie1 flag
	cjne    a,#24d,errt48           ;the service time of the ie1 must be 24
	mov     a,t0_int_flag           ;test the service time of the timer0 flag
	cjne    a,#31d,errt49           ;the service time of the timer0 must be 31	
	mov     a,i0_int_flag           ;test the service time of the ie0 flag
	cjne    a,#32d,errt50           ;the service time of the ie0 must be 32
	jmp	nmi_nmi                 ;continue the test


errt37: sjmp     errt37                 ;error in the service time of the ie13 interrupt
errt38: sjmp     errt38                 ;error in the service time of the ie12 interrupt
errt39: sjmp     errt39                 ;error in the service time of the ie11 interrupt
errt40: sjmp     errt40                 ;error in the service time of the ie10 interrupt
errt41: sjmp     errt41                 ;error in the service time of the ie9 interrupt
errt42: sjmp     errt42                 ;error in the service time of the ie8 interrupt
errt43: sjmp     errt43                 ;error in the service time of the ie7 interrupt
errt44: sjmp     errt44                 ;error in the service time of the ie6 interrupt
errt45: sjmp     errt45                 ;error in the service time of the ie5 interrupt
errt46: sjmp     errt46                 ;error in the service time of the serial interrupt
errt47: sjmp     errt47                 ;error in the service time of the timer1 interrupt
errt48: sjmp     errt48                 ;error in the service time of the ie1 interrupt
errt49: sjmp     errt49                 ;error in the service time of the timer0 interrupt
errt50: sjmp     errt50                 ;error in the service time of the ie0 interrupt
	;-----------------------------------------------------------------------
	;        AN NMI WILL TRY TO INTERRUPT AN NMI SERVICE ROUTINE
	;-----------------------------------------------------------------------
nmi_nmi:;initialize the interrupts
	mov	b,#00h			;clear the glogal flag B
	clr	a			;clear the Acc register
	mov	ie,a			;disable the 5 standard interrupts
	mov	ie1,a			;disable further interrupts
	mov	xintr0,a                ;do not trigger interrupts
	mov     xintr1,a                ;do not trigger interrupts
	;initialize the NMI interrupt flag
	mov	r1,#nmi_int_flag        ;copy int flag of NMI to R1
	mov     @r1,#00h                ;initialize the NMI interrupt flag
	mov     r0,#nmi_counter         ;copy NMI_COUNTER to R0
	mov     @r0,#01h                ;initialize the NMI_COUNTER
	setb	B.1                     ;set the global bit B.1 that will cause
					;an NMI routine to try to interrupt 
					;an NMI routine
	mov	xintr1,#80h             ;trigger the NMI
	nop
	mov	a,nmi_int_flag          ;Copy the NMI_INT_FLAG to Acc for comparison
	nop
	nop
	nop
	nop				;introduce some delay
	nop
	nop
	nop
	mov	xintr1,#00h		;clear the triggering of the NMI
	;compare the results
	cjne    a,#01h,errt51           ;compare NMI_INT_FLAG with 01h
	mov	a,nmi_int_flag          ;Copy the NMI_INT_FLAG to Acc for comparison
	cjne    a,#02h,errt52           ;compare NMI_INT_FLAG with 01h
	jmp     ints1_tst               ;continue the test

errt51: sjmp	errt51			;error an NMI has interrupted an NMI service routine	
errt52: sjmp    errt52                  ;error in the Interrupt controller of the chip
;-------------------------------------------------------------------------------
; This routine works in accordance with the update_registers routine and is used
; not to trigger, each time, the interrupt with the highest priority. This routine
; works from ie13 to ie0 to disable the highest priority of each interrupt
; each time. The routine updates the special function registers
; ESFR_C0, ESFR_C1, SCON, TCON and T2CON.
change_priorityt:
	mov	a,r2			;load Acc with the table entry of ESFR1_TBL
	mov     dptr,#esfr1_tblt	;load DPTR with the address of the ESFR1_TBL table
	movc    a,@a+dptr		;move code byte
	mov	xintr1,a               ;update the ESFR1
	mov	a,r2			;load Acc with the table entry of ESFR0_TBL
	mov     dptr,#esfr0_tblt	;load DPTR with the address of the ESFR0_TBL table
	movc    a,@a+dptr		;move code byte
	mov	xintr0,a               ;update the ESFR0
	mov	a,r2			;load Acc with the table entry of SCON_TBL
	mov     dptr,#scon_tblt		;load DPTR with the address of the SCON_TBL table
	movc    a,@a+dptr		;move code byte
	mov	scon,a                  ;update the SCON register
	mov	a,r2			;load Acc with the table entry of TCON_TBL
	mov     dptr,#tcon_tblt		;load DPTR with the address of the TCON_TBL table
	movc    a,@a+dptr		;move code byte
	mov	tcon,a                  ;update the TCON register
	;-- This code is used for the TIMER2 
	mov	A, config_reg1          ;Copy configuration register into A
	jb      A.0,trq                 ;If TIMER2 is excluded return to the main program
        mov     a, r2                   ;Load Acc with the table entry of timer2_tblt
        mov     dptr, #timer2_tblt      ;Load DPTR with the address of the timer2_tblt table
        movc    a, @a+dptr              ;move code byte
        mov     t2con,a                 ;update the T2CON register
trq:	ret				;return to the main programme
	
timer2_tblt:
	db	80h
	db      80h
	db      80h
	db      80h
	db      80h
	db      80h
	db	80h
	db      80h
	db      00h
	db      80h
	db      80h
	db      80h
	db      80h
	db      80h
	db      80h
	db      80h
	db      80h


esfr1_tblt:
	db	01h
	db	01h
	db	01h
	db	01h
	db	01h
	db	01h
	db	01h
	db	01h
	db	01h
	db	01h
	db	01h
	db	01h
	db      01h
	db	01h
	db	01h
	db      01h
	db      00h

esfr0_tblt:
	db	ffh;0
	db      ffh;1
	db      ffh;2
	db      ffh;3
	db      ffh;4
	db      ffh;5
	db      ffh;6
	db      ffh;7
	db      feh;8
	db      fdh;9
	db      fbh;10
	db      f7h;11
	db      efh;12
	db      dfh;13
	db      bfh;14
	db      7fh;15
	db      ffh;16

scon_tblt:
	db	03h
	db	03h
	db	03h
	db	03h
	db	03h
	db	03h
	db	03h
	db      00h
	db      03h
	db      03h
	db	03h
	db	03h
	db	03h
	db	03h
	db	03h
	db	03h
	db	03h

tcon_tblt:
	db	afh
	db	ach
	db	ach
	db	ach
	db      8fh
	db      a3h
	db      2fh
	db      afh
	db      afh
	db      afh
	db      afh
	db      afh
	db      afh
	db      afh
	db      afh
	db      afh
	db      afh
;-------------------------------------------------------------------------------
; This routine is used to move the priority window (i.e. see iterrupt test plan 
; m8051ew/docs/M8051EW interrupt test plan.doc)
; from ie13 to ie0 and update the IPH, IP, IPH1, IP1 special function registers
update_registerst:
	mov	a,r2                     ;load Acc with the table entry of IPH_TBL
	mov     dptr,#iph_tblt            ;load DPTR with the address of the IPH_TBL table
	movc    a,@a+dptr                ;move code byte
	mov     iph,a                    ;update the priority register IPH
	mov	a,r2                     ;load Acc with the table entry of IP_TBL
	mov     dptr,#ip_tblt             ;load DPTR with the address of the IP_TBL table
	movc    a,@a+dptr                ;move code byte
	mov     ip,a                     ;update the priority register IP
	mov	a,r2                     ;load Acc with the table entry of IPH1_TBL
	mov     dptr,#iph1_tblt           ;load DPTR with the address of the IPH1_TBL table
	movc    a,@a+dptr                ;move code byte
	mov     iph1,a                   ;update the priority register IPH1
	mov	a,r2                     ;load Acc with the table entry of IP1_TBL
	mov     dptr,#ip1_tblt            ;load DPTR with the address of the IP1_TBL table
	movc    a,@a+dptr                ;move code byte
	mov     ip1,a                    ;update the priority register IP1
	ret				 ;return to the main program

iph_tblt:db	00h
	db	00h
	db      01h
	db 	03h
	db 	07h
	db	0eh
	db	1ch
	db	38h
	db 	30h
	db      20h
	db	00h
	db	00h
	db      00h
	db      00h
	db      00h
	db      00h
	db      00h

ip_tblt:db	00h
	db	01h
	db	02h
	db	05h
	db	0ah
	db      15h
	db      2ah
	db      14h
	db      28h
	db      10h
	db      20h
	db      00h
	db      00h
	db      00h
	db      00h
	db      00h
	db      00h

iph1_tblt:db	00h
	db	00h
	db	00h
	db	00h
	db	00h
	db	00h
	db	00h
	db	00h
	db 	01h
	db	03h
	db	07h
	db	0eh
	db	1ch
	db	38h
	db      70h
	db	e0h
	db	c0h

ip1_tblt:db	00h
	db	00h
	db	00h
	db	00h
	db	00h
	db	00h
	db	00h
	db	01h
	db	02h
	db	05h
	db	0ah
	db	15h
	db	2ah
	db	54h
	db	a8h
	db      50h
	db      a0h
	;---------------------------------------------------------------------------
	;                     6 STANDARD INTERRUPTS TEST
	;---------------------------------------------------------------------------
ints1_tst:
	mov    a,config_reg             ;Copy the configuration register into Acc
	jb     a.0,lcall_test1          ;Jump to lcalltest if no uart is present
	jb     a.1,lcall_test1          ;Jump to lcalltest if no timer1,2 are present
	mov    a,config_reg1            ;copy the configuration register 1 into Acc
	jb     a.0, lcall_test1         ;Jump to lcalltest if no TIMER2 is present
	jmp    ints1_tst1
lcall_test1:
	jmp lcalltest			;continue the test
ints1_tst1:
	clr    b.0			;clear the global flag B.0 that causes all
					;the interrupt service routines to 
					;trigger all the interrupts simultaneously
	clr	a			;Clear the Acc register
	mov     ie,a			;disable all interrupts

;ensure timer0 and timer1 are stopped
	orl	p3,#ffh                 ;allow time to see action
	orl     tcon,#50h               
	mov     scon,#0                 ;disable the serial interface
	mov     a,#33h
	mov     tmod,a                  ;initialize TMOD
	clr     a                       ;clear the Acc register
	mov     tl0,a                   ;initialize low byte
	mov     th0,a                   ;initialize high byte
	mov     tl1,a                   ;initialize low byte
	mov     th1,a                   ;initialize high byte
	mov     tcon,#(tcext1control+tcext0control)
	

;initialize all  interrupt flags	
	mov     r1,#i0_int_flag         ;move ie0 int flag
	mov     @r1,#0                  ;clear the ie0 int flag 	
	mov	r1,#t0_int_flag         ;move the timer0 int flag
	mov     @r1,#0                  ;clear the timer0 int flag
	mov	r1,#i1_int_flag         ;move the ie1 int flag
	mov     @r1,#0                  ;clear the ie1 int flag
	mov     r1,#t1_int_flag         ;move the timer1 int flag
	mov     @r1,#0                  ;clear the timer1 int flag
	mov     r1,#tr_int_flag         ;move the serial int flag
	mov     @r1,#0                  ;clear the serial int flag
	mov     r1,#ext05_int_flag      ;move the timer2 int flag
	mov     @r1,#0                  ;clear the timer2 int flag

;test each interrupt in succession with higher priority 
	mov     r2,#6			;move to R2 the number of test permutations
					;of the priority window
	mov	r0,#int_counter         ;move to R0 the interrupt counter
	mov     @r0,#1                  ;initialize the interrupt counter to 1	
	mov     r3,#0                   ;initialize the Loop counter
loopn:  inc	r3                      ;increment the Loop counter
        call    update_registersn       ;change the interrupt priorities
					;through the priority window
	mov     tcon,#afh               ;triger ie1, tf1, ie0, tf0 interrupts
	mov     scon,#03h               ;trigger RI+TI interrupts
	setb    tf2                     ;trigger timer2 interrupt
	mov     ie,#bfh                 ;enable all interrupt sources
        mov     p1,r2                   ;allow interrupt to occur make priority under test visible
	clr     ie.7                    ;disable further interrupts
	djnz    r2,loopn                ;loop until all tested

;test all the service times of the interrupts, error test program
	
	
	mov     a,ext05_int_flag        ;test the service time of timer2
	cjne    a,#6d,errtk1            ;the service time of timer2 must be 6
	mov     a,tr_int_flag           ;test the service time of the serial flag
	cjne    a,#5d,errn1            	;the service time of the serial must be 20
	mov     a,t1_int_flag           ;test the service time of the timer1 flag
	cjne    a,#4d,errn2            	;the service time of the timer1 must be 22
	mov     a,i1_int_flag           ;test the service time of the ie1 flag
	cjne    a,#3d,errn3            	;the service time of the ie1 must be 24
	mov     a,t0_int_flag           ;test the service time of the timer0 flag
	cjne    a,#2d,errn4            	;the service time of the timer0 must be 31	
	mov     a,i0_int_flag           ;test the service time of the ie0 flag
	cjne    a,#1d,errn5            	;the service time of the ie0 must be 32
	jmp	priorityn		;go to the priority test

errtk1:sjmp     errtk1                  ;error in the service time of timer2 interrupt
errn1: sjmp     errn1                   ;error in the service time of the serial interrupt
errn2: sjmp     errn2                   ;error in the service time of the timer1 interrupt
errn3: sjmp     errn3                   ;error in the service time of the ie1 interrupt
errn4: sjmp     errn4                   ;error in the service time of the timer0 interrupt
errn5: sjmp     errn5                   ;error in the service time of the ie0 interrupt

	;------------------------------------------------------------------------
	;            TEST THE 6 MASKABLE INTERRUPTS WITH PRIORITY TEST 
	;------------------------------------------------------------------------
priorityn:
	clr    b.0			;clear the global flag B.0 that causes all
					;the interrupt service routines to 
					;trigger all the interrupts simultaneously
	clr	a			;Clear the Acc register
	mov     ie,a			;disable all interrupts

;ensure timer0 and timer1 are stopped
	orl	p3,#ffh                 ;allow time to see action
	orl     tcon,#50h               
	mov     scon,#0                 ;disable the serial interface
	mov     a,#33h
	mov     tmod,a                  ;initialize TMOD
	clr     a                       ;clear the Acc register
	mov     tl0,a                   ;initialize low byte
	mov     th0,a                   ;initialize high byte
	mov     tl1,a                   ;initialize low byte
	mov     th1,a                   ;initialize high byte
	mov     tcon,#(tcext1control+tcext0control)
	

;initialize all  interrupt flags	
	mov     r1,#i0_int_flag         ;move ie0 int flag
	mov     @r1,#0                  ;clear the ie0 int flag 	
	mov	r1,#t0_int_flag         ;move the timer0 int flag
	mov     @r1,#0                  ;clear the timer0 int flag
	mov	r1,#i1_int_flag         ;move the ie1 int flag
	mov     @r1,#0                  ;clear the ie1 int flag
	mov     r1,#t1_int_flag         ;move the timer1 int flag
	mov     @r1,#0                  ;clear the timer1 int flag
	mov     r1,#tr_int_flag         ;move the serial int flag
	mov     @r1,#0                  ;clear the serial int flag
	mov     r1, #ext05_int_flag     ;move the timer2 int flag
	mov     @r1,#0                  ;clear the timer2 int flag                   
	

;test each interrupt in succession with higher priority 
	mov     r2,#6			;move to R2 the number of test permutations
					;of the priority window
	mov	r0,#int_counter         ;move to R0 the interrupt counter
	mov     @r0,#1                  ;initialize the interrupt counter to 1	
	mov     r3,#0                   ;initialize the Loop counter
loop1n: setb	b.0                     ;enable the global flag B.0 so that each
					;interrupt service routine will jump to its
					;IRQ subroutine to trigger all the interrupts
					;simoultaneously, therefore a higher priority interrupt
					;will interrupt the current interrupt service routine
					;and hence the priority test will take place
	inc	r3                      ;increment the Loop counter
        call    update_registersn       ;change the interrupt priorities
					;through the priority window
	call    change_priorityn        ;trigger all interrupts, except the interrupt with
					;the highest priority, (i.e. priority window)
	mov     ie,#bfh                 ;enable all interrupt sources
        mov     p1,r2                   ;allow interrupt to occur make priority under test visible
	clr     ie.7                    ;disable further interrupts
	djnz    r2,loop1n               ;loop until all tested

;test all the service times of the interrupts, error test program
	
	
	mov     a,ext05_int_flag        ;test the service time of the timer2 flag
	cjne    a,#12d,errnj1           ;the service time of timer2 must be 12
	mov     a,tr_int_flag           ;test the service time of the serial flag
	cjne    a,#10d,errn6           	;the service time of the serial must be 10
	mov     a,t1_int_flag           ;test the service time of the timer1 flag
	cjne    a,#8d,errn7            	;the service time of the timer1 must be 8
	mov     a,i1_int_flag           ;test the service time of the ie1 flag
	cjne    a,#6d,errn8            	;the service time of the ie1 must be 6
	mov     a,t0_int_flag           ;test the service time of the timer0 flag
	cjne    a,#4d,errn9            	;the service time of the timer0 must be 4	
	mov     a,i0_int_flag           ;test the service time of the ie0 flag
	cjne    a,#11d,errn10           ;the service time of the ie0 must be 11
	jmp	lcalltest               ;continue the test

errnj1:sjmp     errnj1                  ;error in the service time of the timer2 interript
errn6: sjmp     errn6                   ;error in the service time of the serial interrupt
errn7: sjmp     errn7                   ;error in the service time of the timer1 interrupt
errn8: sjmp     errn8                   ;error in the service time of the ie1 interrupt
errn9: sjmp     errn9                   ;error in the service time of the timer0 interrupt
errn10:sjmp     errn10                  ;error in the service time of the ie0 interrupt




;-------------------------------------------------------------------------------
; This routine works in accordance with the update_registers routine and is used
; not to trigger, each time, the interrupt with the highest priority. This routine
; works from RI+TI to ie0 to disable the highest priority of each interrupt
; each time. The routine updates the special function registers
; SCON and TCON.
change_priorityn:
	mov     a,r3                    ;load ACC with the table entry of SCON_TBL
	mov     dptr,#scon_tbln		;load DPTR with the address of the SCON_TBL table
	movc    a,@a+dptr		;move code byte
	mov	scon,a                  ;update the SCON register
	mov	a,r3			;load Acc with the table entry of TCON_TBL
	mov     dptr,#tcon_tbln		;load DPTR with the address of the TCON_TBL table
	movc    a,@a+dptr		;move code byte
	mov	tcon,a                  ;update the TCON register
	mov     a,r3                    ;load Acc with the table entry of T2CON
	mov     dptr,#t2con_tbln        ;load DPTR with the address of the T2CON_TBL table
	movc    a,@a+dptr               ;move code byte
	mov     t2con,a                 ;update the T2CON register
	ret				;return to the main programme


scon_tbln:
	db	00h
	db	03h
	db	03h
	db	03h
	db	03h
	db	00h
	db      03h
	db	00h

tcon_tbln:
	db	00h
	db	ach
	db	8fh
	db	a3h
	db      2fh
	db      afh
	db      afh
	db      00h
	
t2con_tbln:
	db	00h
	db      80h
	db      80h
	db      80h
	db      80h
	db      80h
	db      00h
	db      00h 
;-------------------------------------------------------------------------------
; This routine is used to move the priority window (i.e. see iterrupt test plan 
; m8051e/docs/M8051EW interrupt test plan.doc)
; from RI+TI to ie0 and update the IP special function register
update_registersn:
	mov	a,r3                     ;load Acc with the table entry of IPH_TBL
	mov     dptr,#ip_tbln             ;load DPTR with the address of the IP_TBL table
	movc    a,@a+dptr                ;move code byte
	mov     ip,a                     ;update the priority register IP	
	ret				 ;return to the main program

ip_tbln:db	00h
	db	01h
	db      02h
	db 	04h
	db 	08h
	db	10h
	db      20h
	db      00h

	;---------------------------------------------------------------------------
;=========
lcalltest:
;=========
;
; test lcall instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	lcall	initialise	;initialise for test
;
;================
;BRANCH-ljmp test
;================
;
;========
ljmptest:
;========
;
; test ljmp instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	ljmp	ljmpret			;try to long jmp
	error	E_ljmp_fwd_failed	;failed to take long jump
;
ljmpcont:
	nop
;
;================
;BRANCH-sjmp test
;================
;
;========
sjmptest:
;========
;
; test short jmp instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	sjmp	$sjmp2
	error	E_sjmp_forward		;failed to take short jump (forward)
;
$sjmp1:	sjmp	jmptest	
	error	E_sjmp_forward		;failed to take short jump (forward)
;
$sjmp2:	sjmp	$sjmp1
	error	E_sjmp_backward		;failed to take short jump (backward)
;
;================
;BRANCH-jmp test
;================
;
;=======
jmptest:
;=======
;
; test jmp instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	mov	a,#4     		;initialise a to 4
	mov	dptr,#j_tbl		;initialise dptr
	jmp	@a+dptr			;jump trough table
;
j_tbl:	ajmp	inc_error		;error
	ajmp	inc_error
	ajmp	set_acc			;proper entry
	ajmp	inc_error
;
; --------------
; table routines
; --------------
;
inc_error:
	error	E_jmp_indirect	;failed to jump via jump table
;
set_acc:
	mov	a,#dataff		;set a to ffh
	cjne	a,#dataff,$jmp1
	sjmp	jnztest
;
$jmp1:	error	E_jmp_indirect	;failed to set acc after jmp

;================
;BRANCH-jnz test
;================
;
;=======
jnztest:
;=======
;
; test jump on acc not zero instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	mov	a,#data1		;initialise a to 1
	jnz	$jnz1
	error	E_jnz_zero_not_set	;failed jnz : zero not set
;
$jnz1:	dec	a			;decrement a
	jnz	$jnz2			;j if not zero
	sjmp	jztest
;
$jnz2:	error	E_jnz_zero_not_clear	;failed jnz : zero not clear
;
;================
;BRANCH-jz test
;================
;
;======
jztest:
;======
;
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	clr	a			;initialise a to 0
	jz	$jz1
	error	E_jz_zero_not_set	;failed jz : zero not set
;
$jz1:	inc	a			;increment a
	jz	$jz2
	sjmp	jbtest
;
$jz2:	error	E_jz_zero_not_clear	;failed jz : zero not cleared
;
;================
;BRANCH-jb test
;================
;======
jbtest:
;======
;
; test boolean variable jump on bit set instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
; note some jmp instructions already tested in branch.asm
;
;
	mov	reg20,#data80		;initialise value at 20h to 80h
	jb	addrbit7, $jb1		; test MSB of data register 20h
	error	E_jb_direct		;failed to branch on bit set
;
$jb1:	clr	addrbit7			;clear value at 20h
	jb	addrbit7,$jb2
	sjmp	$jbc
$jb2:	error	E_jb_direct		;failed to branch on direct bit set
;
$jbc:	mov	b,#data80		;initialise b to 80h
	jbc	b.7,$jbc1		;jump bit 7 set and clear bit 7
	error	E_jbc_direct		;failed to branch on bit set
;
$jbc1:	jbc	b.7,$jbc2		;see if still set
	sjmp	jctest
;
$jbc2:	error	E_jbc_direct		;failed to set bit
;
;======
jctest:
;======
;
; test boolean variable jump on carry set instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
; note some jmp instructions already tested in branch.asm
;
;
	clr	c			;clear carry
	cpl	c			;complement carry
	jc	$jc1
	error	E_jc_carrynotset	;failed to jump on carry
;
$jc1:	clr	c			;clear carry
	jc	$jc2
	sjmp	jnbtest
$jc2:	error	E_jc_carryset		;failed to jump on carry clear
;
;=======
jnbtest:
;=======
;
; test boolean variable jnb set instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
; note some jmp instructions already tested in branch.asm
;
;
	mov	reg20,#data7f		;initialise value at 20h to 7fh
	jnb	addrbit7,$jnb1
	error	E_jnb_bitset		;bit is set incorrectly
;
$jnb1:	mov	reg20,#data80		;set bit7 to 1
	jnb	addrbit7,$jnb2
	sjmp	jnctest
$jnb2:	error	E_jnb_bitnotset		;failed if bit not set
;
;=======
jnctest:
;=======
;
; test boolean variable jnc set instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
; note some jmp instructions already tested in branch.asm
;
	clr	c			;clear carry
	jnc	$jnc1
	error	E_jnc_carryset		;carry set when it should not have been
;
$jnc1:	cpl	c			;set carry
	jnc	$jnc2
	sjmp	cjnetest
$jnc2:	error	E_jnc_carrynotset	;carry not set whne it should have been
;
;================
;BRANCH-cjne test
;================
;
;========
cjnetest:
;========
;
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	mov	a,#data55		;initialise a to 55h
	cjne	a,#data55,$cjne1	;compare to 55h
	sjmp	$cjne2
$cjne1:	error	E_cjne_a_imm_zero_not_set ;failed. cjne jmp taken wrongly
;
$cjne2:	cjne	a,#data2,$cjne3		;compare to 2
	error	E_cjne_a_imm_zero_not_clear ;failed. cjne jmp not taken
;
$cjne3:	mov	b,#dataaa		;initialise b to aah
	mov	a,#dataaa		;initialise a to aah
	cjne	a,b,$cjne4		;compare a to b
	sjmp	djnztest
$cjne4:	error	E_cjne_ab_zero_not_set 	;failed cjne a,b taken wrongly
;
;================
;BRANCH-djnz test
;================

;========
djnztest:
;========
;
; test decrement and jump instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	mov	r0,#data2		;initialise r0 to 2
	clr	a			;initialise a to 0
$djnz1:	add	a,#data1		;add 1 to a
	djnz	r0,$djnz1
	cjne	a,#data2,$djnz2		;compare a to 2
	sjmp	retitest
;
$djnz2:	error	E_djnz_reg_failed	;failed to loop on djnz
;
;================
;BRANCH-reti test
;================

;=======
retitest:
;=======
;
; test return from interrupt instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	mov	a,#data0		;initialise a to 0
	lcall	ret_int
	cjne	a,#data55,$reti1	;compare a to 55h
	sjmp	noptest		
;
$reti1:	error	E_reti_failed		;failed return from int test
;
;
;================
;BRANCH-nop test
;================
;=======
noptest:
;=======
;
; test nop instruction
;
; entry:
;  exit: nothing affected
;
	nop
	
;================
;LOGICAL-anl test
;================
;=======
anltest:
;=======
;
; test anl instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	mov	a, #33h			; initialise accumulator to 33h
	mov	r6, #0Fh		; initialise r6 to 0fh
	anl	a, r6			; AND accumulator with r6
	dec	a			; acc starts at 03h
	dec	a
	dec	a
	jz	$ant1			; test for the correct result
	error	E_anl_a_direct 		; failed to set zero flag on anl

; ensure we can AND carry bit with all bits in B register
 
$ant1:	mov	b,#dataff		; initialise b to ff
	mov	a,#dataff		; initialise acc to ffh
	add	a,#data1		; add 1 to a to get carry
	anl	c,b.0			; AND carry flag with b.0
	anl	c,b.1			; AND carry flag with b.1
	anl	c,b.2			; AND carry flag with b.2
	anl	c,b.3			; AND carry flag with b.3
	anl	c,b.4			; AND carry flag with b.4
	anl	c,b.5			; AND carry flag with b.5
	anl	c,b.6			; AND carry flag with b.6
	anl	c,b.7			; AND carry flag with b.7
	mov	a,#data0		; clear accumulator
	addc	a,#data0		; add carry to accumulator
	cjne	a,#data1,$ant14
	sjmp	$ant15			; logical or test
$ant14:	error	E_anl_c_breg		; failed carry and b reg test
;
$ant15:	mov	b,#data2		; initialise b to 2
	mov	a,#dataff		; initialise acc to ffh
	add	a,#data1		; add 1 to acc to get carry
	anl	c,b.1			; AND carry flag with b.1
	mov	a,#data0		; clear accumulator
	addc	a,#data0		; add carry to accumulator
	cjne	a,#data1,$ant16
	sjmp	orltest			

$ant16:	error	E_anl_carry_breg	; failed to and carry with b reg
;
;================
;LOGICAL-orl test
;================
;=======
orltest:
;=======
;
; test logical OR instructions
;
	mov	r0, #47h		; initialise pointer register
	mov	47h, #ABh		; initialise memory location 47h
	mov	48h, #58h		; initialise memory location 48h
	mov	49h, #0			; initialise memory location 49h

	mov	a, #11h			; initialise acc to 11h
	mov	r7, #12h		; initialise r7 to 12h
	orl	a, r7			; OR contents of acc with r7
	cjne	a, #13h, $orl1		; test for correct result in acc
	sjmp	$orl2
$orl1:	error	E_orl_a_direct		; failed a orl register test

$orl2:	clr	a
	orl	a, #01h			; ORL acc with immmediate byte
	jz	$orl1
	orl	a, 48h			; ORL acc with address 48h
	orl	a, @r0			; ORL acc with address 47h
	cjne	a, #FBh, $orl1		; test for correct acc result
	orl	49h, a			; ORL address 49h with acc
	clr	a			; clear accumulator
	xch	a, 49h			; exchange acc with address 49h
	cjne	a, #FBh, $orl1		; test for correct result

$orl3:	mov	a, #data1
	cpl	a
	mov	b, a			; copy value FEh to B register
	clr	c			; clear carry flag
	orl	c, /b.0			; OR carry flag with comp of b.0
	jnc	orl4
	orl	c, /b.1			; OR carry flag with comp of b.1
	orl	c, /b.2			; OR carry flag with comp of b.2
	orl	c, /b.3			; OR carry flag with comp of b.3
	orl	c, /b.4			; OR carry flag with comp of b.4
	orl	c, /b.5			; OR carry flag with comp of b.5
	orl	c, /b.6			; OR carry flag with comp of b.6
	jnc	orl4
	orl	c, b.7			; OR carry flag with b.7
	jc	xrltest			; pass on to the next test
orl4:	error	E_orl_c_breg		; failed to or carry with b reg

;================
;LOGICAL-xrl test
;================
;=======
xrltest:
;=======
;
; test exclusive or instructions
;
; entry: no conditions
;  exit: flags a corrupt
;	 all other register corrupt
;
	mov	a, #0fh			; initialise acc to ffh
	mov	r4, #data55		; initialise r4 to 55h
	xrl	a, r4			; XOR
	cjne	a, #5ah, $xrl1		; acc should equal 5ah
	sjmp	$xrl2
$xrl1:	error	E_xrl_a_direct		; failed to XOR acc and register
;
$xrl2:	mov	a, #data7f		; initialise acc to 7fh
	mov	b, #data80		; initialise b to 80h
	xrl	a, b			; XOR
	cjne	a, #dataff, $xrl3
	sjmp	clrtest

$xrl3:	error	E_xrl_a_breg		; failed to xor a and b register

;================
;LOGICAL-clr test
;================
;=======
clrtest:
;=======
;
; test clear a instruction
;
; entry: no conditions
;  exit: flags a corrupt
;	 all other registers corrupt
;
;
	clr	a			;clear a
	cjne	a,#data0,$clr1		;compare to zero
	sjmp	$clr2			;go for next test
$clr1:	error	E_clr_a			;failed to clear acc
;
$clr2:	mov	a,#dataff		;initialise a to ffh
	add	a,#data1		;create a carry
	clr	a			;now clear a
	clr	c
	addc	a,#data0		;add carry and 0 to a
	cjne	a,#data1,$clr3		;compare to 1
	error	E_clr_carry		;failed to clear carry
;
$clr3:	mov	b,#dataff		;initialise b to ffh
	mov	a,#data7f		;initialise a to 7fh
	clr	b.7			;clear bit 7
	cjne	a,b,$clr4		;compare a to b
	sjmp	$clr5
$clr4:	error	E_clr_bit		;failed to clear directly addressable bit
;
$clr5:	mov	reg20,#data80		;initialise value at 20h to 80h
	clr	addrbit7			;clear user bit 7
	mov	a,#data0		;initialise a to 0
	cjne	a,reg20,$clr6
	sjmp	cpltest
$clr6:	error	E_clr_bit		;failed to clear bit;
;
;================
;LOGICAL-cpl test
;================
;=======
cpltest:
;=======
;
; test complement a instructions
;
; entry: no conditions
;  exit: flags a corrupt
;	 all other registers corrupt
;
;
	mov	a,#data55		;initialise a to 55h
	cpl	a			;complement a
	cjne	a,#dataaa,$cpl1		;compare to aah
	sjmp	$cpl2			;rotate left test next
$cpl1:	error	E_cpl_a			;failed to complement accumulator
;

;
$cpl2:	clr	c			;clear the carry bit
	mov	a,#data0		;initialise a to 0
	cpl	c			;complement the carry bit
	addc	a,#data0		;add carry and 0 to a
	cjne	a,#data1,$cpl5		;compare to 1
	sjmp	setbtest
$cpl5:	error	E_cpl_carryset		;failed to complement (i.e. set) carry
;

;================
;LOGICAL-setb test
;================
;========
setbtest:
;========
;
; test boolean variable setb and carry instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;	 all other registers corrupt
;
;
	clr	c			;clear carry
	setb	c			;set carry
	jc	$sbt1
	error	E_setb_carrynotset	;carry not set after setb c
;
$sbt1:	mov	reg20,#data0		;clear value at 20h
	setb	addrbit7     		;set bit 7 at 20h
	mov	a,reg20			;get value at 20h
	cjne	a,#data80,$sbt2
	sjmp	rltest
$sbt2:	error	E_setb_bit_direct	;direct bit not set

	clr	a			; clear accumulator
	setb	c			; set carry flag
	mov	E7h, c			; set acc.7 using carry flag
	mov	c, E0h			; clear carry flag using acc.0
	jc	$sbt2			; test for a clear carry flag
	cjne	a, #80h, $sbt2		; test that acc.7 is set

	setb	c			; set carry flag
	anl	c, /E3h			; AND carry flag with NOT acc.3
	jnc	$sbt2			; check that carry remains set
;
;
;================
;LOGICAL-rotate left test without carry
;================
;======
rltest:
;======
;
; test rotate left instructions
;
; entry: no conditions
;  exit: flags a corrupt
;	 all other registers corrupt
;
;
	mov	a,#data80		;initialise a to 80h
	rl	a			;rotate left
	cjne	a,#data1,$rl1
	sjmp	rlctest
$rl1:	error	E_rl_a_b0clear		;failed to rotate a left one bit
;
;================
;LOGICAL-rotate left test with carry
;================
;======
rlctest:
;======
;
; test rotate left carry instructions
;
; entry: no conditions
;  exit: flags a corrupt
;	 all other registers corrupt
;
;
	mov	a,#data80		;initialise a to 80h
	clr	c			;clear carry
	cpl	c			;set carry
	rlc	a			;rotate left
	jc	$rlc1			;carry should be set
	error	E_rlc_carryclear	;failed to set carry when rotate left
;
$rlc1:	cjne	a,#data1,$rlc2		;a should equal 1
	sjmp	rrtest
$rlc2:	error	E_rlc_a_b0clear		;failed rlc test
;
;================
;LOGICAL-rotate right test without carry
;================
;======
rrtest:
;======
;
; test rotate right instructions
;
; entry: no conditions
;  exit: flags a corrupt
;	 all other registers corrupt
;
;
	mov	a,#data1		;initialise a to 1
	rr	a			;rotate right
	cjne	a,#data80,$rr1
	sjmp	rrctest
$rr1:	error	E_rr_a_b7clear			;failed to rotate a right
;
;================
;LOGICAL-rotate right test with carry
;================
;=======
rrctest:
;=======
;
; test rotate right carry instructions
;
; entry: no conditions
;  exit: flags a corrupt
;	 all other registers corrupt
;
;
	clr	c			;clear carry
	cpl	c			;set carry
	mov	a,#data1		;initialise a to 1
	rrc	a			;rotate right
	jc	$rrc1			;carry should be set
	error	E_rrc_carryclear	;failed to set carry with rotate right
;
$rrc1:	cjne	a,#data80,$rrc2		;a should equal 80h
	sjmp	swaptest		;swap nibbles in a
;
$rrc2:	error	E_rrc_a_b7clear		;failed to set bit 7
;
;================
;LOGICAL-swap test 
;================
;=======
swaptest:
;=======
;
; test swap nibbles in instructions
;
; entry: no conditions
;  exit: flags a corrupt
;	 all other registers corrupt
;
;
	mov	a,#data30		;initialise a to 30h
	swap	a			;swap digits
	cjne	a,#data2+data1,swap_1
        mov     psw, #18h		; select register bank 3
        mov     1Ah, #ABh		; load R2 directly
	mov	18h, #7Fh		; load R0 with indirect address
	mov	a, #CDh
	mov	@r0, a
	mov	a, #34h
	xch	a, r2
	xch	a, @r0
	cjne	r2, #34h, swap_2	; check without changing r2
        cjne	a, #CDh, swap_2 	; check without changing acc
        cjne	@r0, #ABh, swap_2	; check without changing @r0
	xchd	a, @r0			; test digit exchange
	xrl	a, #CBh			; only lower nibbles are changed
	jnz	swap_3			; check accumulator result
	cjne	@r0, #ADh, swap_3	; check register result
	anl	psw, #0			; restore register bank number
	sjmp	flagtest
	
;
swap_1:	error	E_swap_a		; failed to swap nibbles
swap_2:	error	E_xch_a			; failed to exchange bytes
swap_3:	error	E_xchd_a		; failed to exchange digits


;============
flagtest:
;============
;
; test 8051 flags
;
; entry: no conditions
;  exit: flags other registers corrupt
;
;
;
	lcall	initialise
;
	clr	c			:clear carry
	mov	a,#dataff		;initialise a to ffh
	add	a,#data1		;add 1 to a
	jc	$ft01			;carry should be set
	error	E_carry_not_set		;failed to set carry

$ft01:	mov	a,#dataf		;initialise a to 0fh
	add	a,#data1		;add 1 to a
	jb	ac,$ft02		;auxilliary carry should be set

	error	E_auxcarry_not_set		;failed to set auxiliary carry
;
$ft02:	mov	a,#data80		;initialise a to 80h
	add	a,#dataff		;add ffh to a
	jb	ov,$ft03		;overflow should be set
	error	E_ovflow_not_set		;failed to set overflow

$ft03:	mov	a,#data7f		;initialise a to 7fh
	add	a,#data1		;add 1 to a
	jb	ov,$ft04		;overflow should be set
	error	E_ovflow_not_set		;failed to set overflow
;
$ft04:	clr	c			;clear carry
	mov	a,#dataff		;initialise a to ffh
	addc	a,#data1		;add 1 to a
	jc	$ft05			;carry should be set
	error	E_carry_not_set		;failed to set carry

$ft05:	jb	ac,$ft06		;auxilliary carry also set
	error	E_auxcarry_not_set	;failed aux carry not set

$ft06:	mov	a,#dataff		;initialise a to ffh again
	addc	a,#data0		;add 0 and carry to a
	jc	$ft07			;carry should be set 
	error	E_carry_not_set		;failed carry not set

$ft07:	jb	ac,$ft08		;auxilliary carry also set
	error	E_auxcarry_not_set	;auxiliary carry not set
;
$ft08:	clr	c			;clear carry
	mov	a,#data7f		;initialise a to 7fh
	addc	a,#data1		;add 1 to a
	jb	ov,$ft09		;overflow should be set
	error	E_ovflow_not_set		;failed to set overflow

$ft09:	clr	ov			;clear overflow
	setb	c			;set carry
	mov	a,#data7f		;initialise a to 7fh
	addc	a,#data0		;add 0 and carry to a
	jb	ov,$ft010		;overflow should be set
	error	E_ovflow_not_set		;failed to set overflow
;
$ft010:	clr	ov			;clear overflow
	clr	c			;clear carry
	mov	a,#dataff		;initialise a to ffh
	addc	a,#data80		;add 80h to a
	jb	ov,$ft011		;overflow should be set
	error	E_ovflow_not_set		;failed to set overflow

$ft011:	clr	ov			;clear overflow
	setb	c			;set carry
	mov	a,#data80		;initialise a to 80h
	addc	a,#data80		;add 80h and carry to a
	jb	ov,$ft012		;overflow should be set
	error	E_ovflow_not_set		;failed to set overflow
;
$ft012:	clr	ov			;clear overflow
	clr	c			;clear carry
	clr	ac			;clear auxilliary carry
	mov	a,#data0		;initialise a to 0
	subb	a,#data1		;subtract 1
	jc	$ft013			;carry should be set
	error	E_carry_not_set		;carry flag not set

$ft013:	jb	ac,$ft014		;auxilliary carry should be set
	error	E_auxcarry_not_set	;failed to set aux carry

$ft014:	clr	ac			;clear auxilliary carry
	setb	c			;set carry
	mov	a,#data0		;initialise a to 0
	subb	a,#data0		;subtract 0 and carry
	jc	$ft015			;carry should be set
	error	E_carry_not_set		;failed to set carry

$ft015:	jb	ac,$ft016		;auxilliary should be set
	error	E_auxcarry_not_set	;failed to set aux carry

$ft016:	clr	ac			;clear auxilliary carry
	clr	c			;clear carry
	mov	a,#data0		;initialise a to 0
	subb	a,#data0		;subtract 0
	jnc	$ft017			;carry should be cleared
	error	E_carry_not_clear		;failed to clear carry

$ft017:	jnb	ac,$ft018		;no auxilliary carry
	error	E_auxcarry_not_clear	;failed to clear aux carry
;
$ft018:	clr	c			;clear carry
	clr	ac			;clear aux carry
	clr	ov			;clear overflow
	mov	a,#data0		;initialise a to 0
	subb	a,#data80		;subtract 80h
	jb	ov,$ft019		;overflow should be set
	error	E_carry_not_clear		;failed to clear carry

$ft019:	clr	c			;clear carry
	subb	a,#data0		;subtract 0
	jnb	ov,$ft020		;no overflow
	error	E_ovflow_not_clear	;failed to clear overflow

$ft020:	mov	a,#data80		;initialise a to 80h
	setb	c			;set carry
	subb	a,#data0		;subtract 0 and carry
	jb	ov,$ft021		;overflow should be set
	error	E_ovflow_not_set		;failed to set overflow

$ft021:	clr	c			;clear carry
	clr	ov			;clear overflow
	mov	a,#data80		;initialise a to 80h
	subb	a,#data7f		;subtract 7fh
	jb	ov,$ft022		;overflow should be set
	error	E_ovflow_not_set		;failed to set overflow

$ft022:	subb	a,#data0		;subtract 0
	jnb	ov,$ft023		;overflow should be cleared
	error	E_ovflow_not_clear	;failed to clear overflow
;
$ft023:	setb	c			;set carry
	setb	ov			;set overflow
	mov	a,#datafb		;initialise a to fbh
	mov	b,#data12		;initialise b to 12h
	div	ab			;divide
	jnc	$ft024			;carry should be cleared
	error	E_carry_not_clear		;failed to clear overflow

$ft024:	jnb	ov,$ft025		;overflow should be cleared
	error	E_ovflow_not_clear	;failed to clear overflow

$ft025:	setb	c			;set carry
	mov	a,#data2		;initialise a to 2
	mov	b,#data0		;initialise b to 0
	div	ab			;divide
	jnc	$ft026			;carry should be cleared
	error	E_carry_not_clear		;failed to clear carry

$ft026:	jb	ov,$ft027		;overflow should be set
	error	E_ovflow_not_set		;failed to clear overflow
;
$ft027:	clr	c			;clear carry
	clr	ov			;clear overflow
	clr	ac			;clear aux carry
	mov	a,#data1		;initialise a to 1
	cjne	a,#data2,$ft028
	nop

$ft028:	jc	$ft029			;carry should be set
	error	E_carry_not_set		;failed to set carry

$ft029:	cjne	a,#data0,$ft030
	nop

$ft030:	jnc	$ft031			;carry should be cleared
	error	E_carry_not_clear		;failed to clear carry

$ft031:	mov	a,#data80		;initialise a to 80h
	cjne	a,#dataff,$ft032
	nop

$ft032:	jc	$ft033
	error	E_carry_not_set		;failed to set carry

$ft033:	cjne	a,#data7f,$ft034
	nop
$ft034:	jnc	$ft035			;carry should be cleared
	error	E_carry_not_clear		;failed to clear carry
;
$ft035:	setb	c			;set carry
	clr	ov			;clear overflow
	mov	a,#data50		;initialise a to 50h
	mov	b,#dataa0		;initialise b to a0h
	mul	ab			;multiply
	jnc	$ft036			;carry should be cleared
	error	E_carry_not_clear		;failed to clear carry

$ft036:	jb	ov,$ft037		;overflow should be set
	error	E_ovflow_not_set		;failed to set overclow

$ft037:	mov	a,#data2		;initialise a to 32h, b == 32h
	mul	ab			;multiply
	jnb	ov,$ft038		;overflow should be cleared
	error	E_ovflow_not_clear	;failed to clear overflow
;
$ft038:	clr	c			;clear carry
	clr	ac			;clear aux carry
	clr	ov			;clear overflow
	mov	a,#data30		;initialise a to 30h
	add	a,#data99		;add 99h to a
	da	a			;decimal adjust
	jc	$ft039			;carry should be set
	error	E_carry_not_set		;failed to clear carry

$ft039:	mov	a,#data56		;initialise a to 56h
	mov	r3,#data67		;initialise r3 to 67h
	addc	a,r3			;add with previous carry
	jnc	$ft040			;carry should be cleared
	error	E_carry_not_clear		;failed to clear carry

$ft040:	jnb	ac,$ft041		;aux carry should be clear
	error	E_auxcarry_not_clear	;failed to clear aux carry

$ft041:	da	a			;decimal adjust
	jc	$ft042			;carry should be set
	error	E_carry_not_set		;failed to set carry
;
$ft042:	clr	c			;clear carry
	mov	a,#data80		;initialise a to 80h
	rlc	a			;rotate left
	jc	$ft043			;carry should be set
	error	E_carry_not_set		;failed to set carry

$ft043:	jz	$ft044			;a should be 0
	error	E_zero_not_set		;failed to clear acc and set zero

$ft044:	rlc	a			;rotate left again
	jnc	$ft045			;carry should be cleared
	error	E_carry_not_clear	;failed to clear carry

$ft045:	cjne	a,#data1,$ft046		;a should equal 1
	sjmp	$ft047
$ft046:	error	E_zero_not_clear	;failed to clear acc and zero
;
$ft047:	clr	c			;clear carry
	mov	a,#data1		;initialise a to 1
	rrc	a			;rotate right
	jc	$ft048			;carry should be set
	error	E_carry_not_set		;failed to set carry
$ft048:	jz	$ft049			;a should equal 0
	error	E_zero_not_set		;failed to clear acc and set zero

$ft049:	rrc	a			;rotate right again
	jnc	$ft050			;carry should be cleared
	error	E_carry_not_clear		;failed to clear carry

$ft050:	cjne	a,#data80,$ft051    ;a should equal 80h
	sjmp	addtest
$ft051:	error	E_zero_not_clear	;failed to clear acc and zero
;
;============
;ARITH-add test
;============
;=======
addtest:
;=======
;
; test add instructions

	mov     a, #01h
	mov     r5, #02h                ; initialise a and r5
	add     a, r5                   ; add
	cjne    a, #03h, add_er         ; check if we have 3

	mov     b, #80h 
	mov     a, #02h                 ; initialise a and b
	add     a, b                    ; add
	cjne    a, #82h, add_er

	mov     r1, #6fh                ; get pointer to 6fh
	mov     @r1, #02h               ; initialise value at 6fh
	mov     a, #34h                 ; initialise a
	add     a, @r1                  ; add
	cjne    a, #36h, add_er

	mov     a, #f0h                 ; initialise a
	add     a, #02h                 ; add data2 to a
	cjne    a, #f2h, add_er
	sjmp    addctest

add_er: sjmp    add_er                  ; failed to add
;============
;ARITH-addc test
;============
;========
addctest:
;========
;
; test add carry instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;        all other registers corrupt
;
;
	mov     a, #01h                 ; initialise accumulator
	mov     r3, #ffh                ; initialise register 3
	mov	23h, #34h		; initialise address 23h
	mov     psw, #0                 ; make sure carry flag is clear
	addc    a, r3                   ; add r3 and carry flag to acc 
	jz      adc00                   ; test for result of zero in acc
	error   E_addc_zeronotset       ; failed if not zero
adc00:  jc      adc04                   ; test the carry flag
	error   E_addc_carrynotset      ; failed if carry flag not set

	cpl	D7h			; set the carry flag 
	addc	a, 23h			; add contents of 23h and carry
	jc	adc05			; carry flag should be reset
	xrl	a, #35h			; test acc for correct result
	jnz	adc05			; go to an error loop on failure

adc04:  clr	c			: clear carry flag
	mov     r1, #6fh                ; set pointer to 6fh
	mov     @r1, #34h               ; initialise value at 6fh to 34h
	mov     a, #34h                 ; initialise acc to 34h
	addc    a, @r1                  ; add @r1 and carry flag to acc
	cjne    a, #68h, adc05          ; check if result = 68h
	sjmp    subbtest		; pass on to the next test

adc05:  error   E_addc_acc_indirect     ; failed to add indirect loop
;
;
;============
;ARITH-subb test
;============
;========
subbtest:
;========
;
; test subtract instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;        all other registers corrupt
;
;
	mov     a, #02h                 ;initialise a to 2
	mov     r2, #01h                ;initialise r2 to 1
	setb    c                       ;set carry
	subb    a, r2                   ;subtract
	jz      sbb1                    ;a should equal 0
	error   E_subb_acc_reg          ;failed to subtract reg from acc
;
sbb1:   mov     a, #7fh                 ;initialise a to 7fh
	mov     b, #02h                 ;initialise b to 2
	clr     c                       ;clear carry
	subb    a, b                    ;subtract
	cjne    a,#7dh, sbb2
	sjmp    inctest
sbb2:   error   E_subb_a_breg           ;failed to subtract a from b
;

;============
;ARITH-inc test
;============
;=======
inctest:
;=======
;
; test increment instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;        all other registers corrupt
;
;
	clr     a                       ; clear accumulator
	setb	c			; set carry flag
	inc     a                       ; increment accumulator
	jnc	inc_er			; carry should remain unaffected
	cjne    a, #01h, inc_er		; result in accumulator is one

	orl	a, #FFh			; set accumulator to FFh
	inc	E0h			; increment accumulator
	jnz	inc_er			; accumulator result is zero

	mov	r5, #ACh		; load register five
	mov	r0, #04h		; load register zero
	inc	r0			; increment r0 to point to r5
	inc	@r0			; increment r5 using r0  
	mov	a, r5			; load accumulator with r5
	xrl	a, #ADh			; XOR with correct result
	jnz	inc_er			; accumulator should be zero

	clr	c			; clear carry flag
	mov     dpl, #ffh               ; initialise DPTR to FFh
	mov     dph, #ffh
	inc     dptr                    ; increment DPTR
	jc	inc_er			; carry should remian unaffected
	mov     a, dpl                  ; copy DPTR low byte to acc
	cjne    a, #0, inc_er
	mov     a, dph                  ; copy DPTR high byte to acc
	cjne    a, #0, inc_er
	sjmp    dectest			; pass on to the next test

inc_er: sjmp    inc_er                  ; failed to increment error loop

;=======
dectest:
;=======
;
; test decrement instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;        all other registers corrupt
;
;
	clr     a                       ; clear accumulator
	dec     a                       ; decrement accumulator
	cjne    a, #ffh, dec_er         ; compare with FFh

	mov     r7, #0                  ; initialise register 7 to zero
	dec     r7                      ; decrement register 7
	cjne    r7, #ffh, dec_er        ; compare with FFh

	mov	b, #89h			; load register B with 89h
	dec	b			; decrement register B
	mov	a, #88h			; load acc with expected result
	cjne	a, b, dec_er		; test for the correct result

	mov     r1, #20h                ; set pointer register to 20h
	mov     @r1, #0                 ; initialise address 20h to zero
	dec     @r1                     ; decrement contents of @r1
	mov     a, @r1                  ; copy result to accumulator
	cjne    a, #ffh, dec_er		; test for the correct result
	sjmp    multest			; pass on to next test

dec_er: sjmp    dec_er                  ; failed to decrement error loop
;
;ARITH-multiply test
;=======
multest:
;=======
;
; test mul instructions

; multiply to make 16 bit number
; and check that the right values are in each register
;
	setb    c                       ; set carry
	clr     ov                      ; clear overflow (OV) flag
	mov     a, #50h                 ; initialise a to 50h
	mov     b, #a0h                 ; initialise b to a0h
	mul     ab                      ; multiply
	jc      mul_jp                  ; carry should clear unconditionally
	jb      ov, mul1                ; overflow should set
	sjmp    mul_jp
mul1:   jnz     mul_jp                  ; a should be zero (low byte of 3200h)
	mov     a, #32h                 ; initialise a to 32h
	cjne    a, b, mul_jp            ; b should be 32h (high byte of result)
	setb    c
	setb    ov                      ; set overflow flag
	mov     a, #0ah
	mov     b, #0bh                 ; set up new multiplicands
	mul     ab                      ; multiply
	jc      mul_jp                  ; carry should clear unconditionally
	jb      ov, mul_jp              ; overflow flag should be clear
	cjne    a, #6eh, mul_jp         ; expected result of 0ah x 0bh
	mov     a, b                    ; load upper byte of result into acc.
	jz      mul2                    ; should be zero

mul_jp: ljmp    mul_er                  ; Intermediate hop to error handler

mul2:   setb    c                       ; set carry flag
	setb    ov                      ; set overflow flag
	mov     b,#2Bh
	mov     a,#3                    ; set new multiplicands
	mul     ab                      ; multiply
	jc      mul_er                  ; carry flag should be clear
	jb      ov, mul_er              ; overflow flag should be clear
	cjne    a, #81h, mul_er         ; expected result of 2Bh x 3
	mov     a, b                    ; load upper byte of result into acc.
	jnz     mul_er                  ; should be zero
	sjmp	divtest

mul_er: sjmp    mul_er                  ; multiply fail loop
;
;============
;ARITH-divide test
;============
;========
divtest:
;========
;
; test division instructions
;
	setb    c                       ; set carry
	setb    ov                      ; set overflow (OV) flag
	mov     a, #fbh                 ; initialise a to fbh
	mov     b, #12h                 ; initialise b to 12h
	div     ab                      ; divide
	cjne    a, #0dh, div_er         ; compare a to 13 (0dh)
	mov     a, b                    ; mov b to a
	cjne    a, #11h, div_er         ; compare to 11h, expected remainder
	jc      div_er                  ; carry should clear unconditionally
	jb      ov, div_er              ; overflow should clear
	cpl     c                       ; set carry
	clr     ov                      ; clear overflow flag
	mov     b, #0                   ; special divisor condition
	div     ab                      ; divide will only define the OV flag
	jc      div_er                  ; carry should clear
	jb      ov, daatest             ; overflow flag set for zero divisor

div_er: sjmp    div_er                  ; failed division. 
;============
;ARITH-decimal adjust accumulator
;============
;=======
daatest:
;=======
;
; test daa instructions

; calculate 56h + 67h + 1 (i.e BCD 56 + BCD 67 + 1) = BCD 124

	mov     a, #56h                 ; initialise a to 56h
	mov     r3, #67h                ; initialise r3 to 67h
	setb    c                       ; set carry
	addc    a, r3                   ; add
	da      a                       ; decimal adjust result
	jb      ac, daa_er              ; auxillary carry should not change
	jnc     daa_er                  ; carry bit should now be set
	cjne    a, #24h, daa_er         ; compare result with 24h

; calculate 30h + 99h = BCD 129

	clr     c                       
	mov     a,#data30               ; initialise a to 30h
	add     a,#data99               ; add 99h to a
	da      a                       ; decimal adjust result
	jb      ac, daa_er              ; auxillary carry should not change
	jnc     daa_er                  ; carry bit should now be set
	cjne    a, #29h, daa_er         ; compare to 29h
	sjmp    miscmov			; pass on to the next test

daa_er: sjmp    daa_er                  ; failed DAA error loop

; Miscellaneous internal move instruction tests

;=======
miscmov:
;=======

	mov	r1, #7Fh		; initialise indirect pointer
	mov	23h, #08h		; initialise data memory store
	mov	24h, #10h		; initialise data memory store
	mov	70h, #00h		; initialise data memory store
	mov	7fh, #20h		; initialise data memory store

	mov	70h, @r1		; indirect to direct memory move
	mov	@r1, 23h		; direct to indirect memory move
	mov	23h, 24h		; direct to direct memory move
	mov	24h, r1			; register to direct memory move

	mov	a, 70h			; recover data from @r1 (20h)
	cjne	a, #20h, movfail	; go to error loop if incorrect
	mov	a, 7Fh			; recover data from 23h
	cjne	a, #08h, movfail	; go to error loop if incorrect
	mov	a, 23h			; recover data from 24h
	cjne	a, #10h, movfail	; go to error loop if incorrect
	mov	a, 24h			; recover data from r1 (7Fh)
	cjne	a, #7Fh, movfail	; go to error loop if incorrect
	sjmp    movc_test		; pass on to next test

movfail:
	sjmp	movfail			; miscellaneous moves error loop
;
; MOVX and MOVC tests
;
;
; entry: no conditions
;  exit: flags, a corrupt
;        all other registers corrupt
;
;
;=========
movc_test:
;=========
	mov     a, #data2		; initialise accumulator with 2
        add     a, #data2        	; account for sjmp code offset
        movc    a, @a+pc         	; get byte from in-line table
        sjmp    $mvc1
;
; MOVC program memory in-line data table
;
$mvc0:  db      dataff         		; initialise to ffh
        db      data55         		; initialise to 55h
        db      dataaa         		; initialise to aah
        db      data7f         		; initialise to 7fh
;
$mvc1:  cjne    a, #dataaa, $mvc2
        sjmp    $mvc3

$mvc2:  error   E_movc_acc_pc		; failed to read table correctly
$mvc3:  mov     dptr, #$mvc0		; point to external program data
        mov     a, #data2+data1		; initialise acc to 3
        movc    a, @a+dptr		; get program memory constant
        cjne    a, #data7f, $mvc4	; which should equal 7fh
        sjmp    movxtest
$mvc4:  error   E_movc_acc_dataptr	; failed to read table correctly
;
;========
movxtest:
;========
;
; test move external instructions
;
; entry: no conditions
;  exit: flags, a corrupt
;        all other registers corrupt
;
	mov	a,config_reg		;copy the config reg to Acc
	jb	a.2,movx_tst            ;continue the test if no ports are present
	jmp     movx_tst1
movx_tst:jmp    popind       

movx_tst1:
        mov     r1, #ext2e       	; set pointer to external 2eh
        clr     a               	; clear accumulator
        movx    @r1, a           	; initialise external data to 0
        inc     r1              	; step to next address 
	inc	a
        movx    @r1, a           	; clear external data memory
        mov     r0, #ext2e       	; get pointer to external 2eh
        mov     a, #dataff      	; initialise acc to ffh
        movx    a, @r0           	; read value (should be 0)
        jz      $mvx2

$mvx1:  error   E_movx_acc_indirect	; failed to move external data 

$mvx2:  inc     r0
        movx    a, @r0
        cjne    a, #01h, $mvx3
	sjmp	$mvx4

$mvx3:	error   E_movx_acc_indirect	; failed to move external data

$mvx4:	mov     dptr, #ext_data  	; initialise DPTR 
        mov     a, #dataaa       	; initialise acc to aah
        movx    @dptr, a         	; store AAh in external byte 1
        cpl     a               	; change acc to 55h
        inc     dptr            	; step address
        movx    @dptr, a         	; store in external byte 2
        mov     dptr, #ext_data  	; re-initialise DPTR
        clr     a               	; clear accumulator
        movx    a, @dptr         	; get first external data byte
        cjne    a, #dataaa, $mvx5
        sjmp    $mvx6

$mvx5:  error   E_movx_dptr_indirect	; failed to MOVX using DPTR

$mvx6:  inc     dptr
        movx    a, @dptr         	; get second external data byte
        cjne    a, #data55, $mvx7
        sjmp    popind

$mvx7:  error   E_movx_dptr_indirect	; failed to MOVX using DPTR

;============
;POPIND
;============
;
popind:
	mov	sp, #01h
	mov	b, #20h
	mov	a, #5ah
;
pop1:	push 	a
	cpl	a
	djnz	b, pop1
 
	mov	a, #10h
pop2:	pop	b
	mov 	r0, b
	cjne	r0, #0a5h, pop_err
	pop	b
	mov	r0, b

	cjne	r0, #05ah, pop_err
	dec	a
	djnz	a, pop2
	sjmp	misc_test
pop_err: 
	sjmp    pop_err
	;-----------------------------------------------------------------
	;                                 MISC TEST
	;-----------------------------------------------------------------
misc_test:
	mov	b,#00h		;clear the B register
	setb	b.7		;set B.7
	cpl	b.7		;complement B.7
	mov	a,b             ;copy b into Acc
	cjne    a,#00h,erre1    ;compare b with 00h
	cpl	b.7		;complement B.7
	mov	a,b		;copy b into Acc
	cjne	a,#80h,erre2    ;compare b with 80h
	mov	c,b.7		;copy B.7 to carry
	mov	b,#0		;clear the B register
	cpl	c		;complement carry
	cpl	c		;complement carry
	mov	b.7,c           ;copy carry to B.7
	mov	a,b		;copy B register to Acc
	cjne    a,#80h,erre3    ;compare B with 80h
	;-------------------------------------------------------------------
	;                        ACALL TEST
	;-------------------------------------------------------------------
	mov	a,#00h		;clear the Acc register
	acall	misc_rt         ;call the misc_rt routine
        cjne    a,#01h,erre4    ;compare Acc with 01h
	;-------------------------------------------------------------------
	;                        AJMP TEST
	;-------------------------------------------------------------------
	mov	a,#00h          ;clear the Acc register
	ajmp	misc_rt1	;jump to misc_rt1
erre5:  sjmp    erre5           ;error in the ajmp instruction
rt2:    cjne	a,#01h,erre6    ;compare Acc with 01h
	;-------------------------------------------------------------------
	;                         JBC TEST
	;-------------------------------------------------------------------
	mov	addr20h,#00h    ;clear the internal data memory 20h
	mov     a,#00h          ;clear the Acc register
	setb	addr20h.0       ;set the bit 0 of the addr20h
	jbc     addr20h.0,jbc_tst;jump if bit.0=1 then clear bit
erre7:  sjmp    erre7           ;error in the JBC instruction
jbc_tst1:cjne   a,#01h,erre8    ;compare Acc with 01h
	mov     a,addr20h       ;copy internal data memory 20h to Acc
	cjne    a,#00h,erre9    ;compare internal address 20h with 00h
	jbc     addr20h.0,jbc_tst2;jump to JBC_TST2 if the internal address 20h.0 is 01h
	mov     a,addr20h       ;copy internal data memory 20h to Acc
	cjne    a,#00h,erre10   ;compare with 00h
	sjmp	serial_pretest

erre1:	sjmp    erre1		;error the B.7 is not 0
erre2:  sjmp    erre2           ;error the B.7 is not 1
erre3:  sjmp    erre3           ;error the carry is not set
erre4:  sjmp    erre4           ;error the Acc register is not 1
erre6:  sjmp    erre6           ;error the Acc register is not 1
erre8:  sjmp    erre8           ;error the Acc register is not 1
erre9:  sjmp    erre9           ;error the internal address 20h is not 00h
erre10: sjmp    erre10          ;error the internal address 20h is not 00h

misc_rt:inc	a		;increment the accumulator
	ret			;return to the main program

misc_rt1:inc	a		;increment the accumulator
	sjmp	rt2

jbc_tst:inc     a		;increment Acc
	jmp	jbc_tst1        ;continue the test
jbc_tst2:sjmp	jbc_tst2        ;error in the JBC instruction
;=======================
; SERIAL INTERFACE TESTS
;=======================
;
;===============
serial_pretest:
;===============
	mov	a,config_reg		;Copy the config_reg to Acc
	jb	a.0,ext_s		;continue the test if the uart is not present
	jb      a.1,ext_s               ;continue the test if the timers are not present
	jb      a.2,ext_s               ;continue the test if the ports are not present
	sjmp	uart_tst
ext_s:  jmp	ext_sfr
;
; test serial port transmit interrupt
; check for unexpected interrupts and also ensure that
; serial interrupt happens at right time.
;
; entry: no conditions
;  exit: flags a corrupt
;	 all other registers preserved
;
;
; first enable test bench loop-back from TXD to RXD using PORT3.7 control
uart_tst:
        mov     p3, #7fh		; enable serial loop back buffer

;
; initialise peripheral SFRs
;
	clr	a
	mov	ie, a			; disable all interrupts
	mov	ip, a			; clear priority
	mov	tmod,a			; initialise tmod
	mov	tl0,a			; initialise low byte
	mov	th0,a			; initialise high byte
	cpl	a
	mov	tl1,a			; initialise low byte
	mov	th1,a			; initialise high byte
	orl	pcon, #80h		; set smod
;
	mov	scon, #0
	mov	tcon, #(tcext1control + tcext0control)
					; select edge-triggered interrupts
;
; check for unexpected interrupt
;
	mov	ie, #(ieenable + ieserialenable)
					; enable int serial
	mov	sbuf, #ffh
	mov	scon, #sctxintflag	; provoke serial int
;
; wait for interrupt timeout
;
	mov	r0, #10
$i0t0:	djnz	r0, $i0t0		; loop until wrap
;
;
;===============
serial_mode_1:
;===============
;
; transmit and receive 91h in mode 1 regardless of 9th bit
	mov	tmod, #20h		; timer 1 in 8 bit reload mode
	mov	tcon, #(tct1on + tcext1control + tcext0control)
					; turn timer1 on

	mov	scon, #50h 		; select serial mode 1 and enable the receiver
        mov	r6, #91h		; load r6 with byte to be transmitted
	lcall	ser_int_check		; check serial interrupt has occurred
        mov	a, r6			; load acc with value transmitted
	cjne	a, sbuf, rx_err		; compare with byte received
        mov	a, #57h			; load acc with expected return value for scon
	cjne	a, scon, rx_err		; compare with current state 
        mov     scon, #70h		; transmit again with SM2 set
        mov	r6, #6Eh		; load r6 with byte to be transmitted
	lcall	ser_int_check		; check serial interrupt has occurred
        mov	a, r6			; load acc with value transmitted
	push	a			; save transmitted word for serial_mode_3 test
	cjne	a, sbuf, rx_err		; compare with byte received
        mov	a, #77h			; load acc with expected return value for scon
	cjne	a, scon, rx_err		; compare with current state 
;
;===============
serial_mode_3:
;===============
;
; transmit A2h in mode 3 regardless of 9th bit
	mov     tl1,  #fch
        mov     th1,  #fch
         				; turn timer1 on
	mov	scon, #scmode3		; select mode 3 for the serial interface
	orl	scon, #34h		; enable receiver and set both SM2 and RB8
        mov	r6, #A2h		; load r6 with byte to be transmitted
	lcall	ser_int_check		; check serial interrupt has occurred
        pop	a			; load acc with last value received
	cjne	a, sbuf, rx_err		; verify that the receiver buffer is unchanged
        mov	a, #F6h			; load acc with expected return value for scon
	cjne	a, scon, rx_err		; compare with current state 

	mov	scon, #F8h		; enable receiver and set both SM2 and TB8
        mov	r6, #B3h		; load r6 with byte to be transmitted
	lcall	ser_int_check		; check serial interrupt has occurred
        mov	a, r6  			; load acc with last value received
	cjne	a, sbuf, rx_err		; verify that the receiver buffer is unchanged
        mov	a, #FFh			; load acc with expected return value for scon
	cjne	a, scon, rx_err		; compare with current state 
;
;===============
serial_mode_2:
;===============
;
; transmit and receive 55h in mode 2 with 9th bit clear
;
	mov	scon, #90h		; select serial mode 2 and enable Rx
        mov	r6, #55h		; load r6 with byte to be transmitted
	lcall	ser_int_check		; check serial interrupt has occurred
        mov	a, r6			; load acc with value transmitted
	cjne	a, sbuf, rx_err		; compare with byte received
        mov	a, #93h			; load acc with expected return value for scon
	cjne	a, scon, rx_err		; compare with current state 

; disable test bench loop-back from TXD to RXD

        mov     p3, #ffh		; disable serial loop back buffer

;
;===============
serial_mode_0:
;===============
;
; transmit 76h in mode 0 and receive the same time-shifted by one bit.
; This test is dependent on the exact coding sequence given for correct timing
;
	mov	scon, #00h		; select serial mode 0
        mov	a, #76h			; load acc with byte to be transmitted
        mov     sbuf, a			; load buffer and start transmission
        setb    scon.4          	; enable receiver to start reception
        setb	c			; wait for transmission to complete
        rrc	a			; calculate byte expected at receiver
        nop
        nop
        nop
        nop
        nop
        nop
        jnb     scon.1, rx_err		; verify that TI is set
        jnb     scon.0, rx_err		; verify that RI is set
        nop
        nop
        nop
	sjmp	ext_sfr 		; pass on to the next group of tests

rx_err:	error   E_ser_data_bad		; failed to receive data transmitted
; External Interface Test
;=======
ext_sfr:
;=======
	mov	r0, #xintr0		; corresponding addr to external SFR
	mov	xintr0, #78h	; load external SFR
	mov	@r0, #CDh		; load corresponding address in memory
	inc	xintr0
	inc	@r0
	mov	a, #79h
	cjne	a, xintr0, esfr1	; ESFR should respond to direct reads
	cjne	@r0, #CEh, esfr1	; data memory responds to indirect reads
	sjmp	psave			; pass on to the next test
esfr1:	error	E_ext_sfr		; external SFR failure loop

; Power saving demonstration
;=====
psave:
;=====
	mov	a,config_reg            ; copy the config register to Acc
	jb	a.1,waitg_tst           ; continue the test if timers are not present  
        anl	tcon, #0fh		; clear timer interrupt sources
	mov	tmod, #02h		; set up timer 0 as an 8 bit timer
	mov	tl0, #FEh		; count two machine cycles before roll
	mov	th0, #00h		; reload value is not important
	mov	ie1, #0h;		; disable extension interrupts
	mov	ie, #82h		; enable timer 0 interrupt
	mov	tcon, #10h		; start timer 0
	mov	pcon, #01h		; go idle and wait for interrupt
	anl	ie, #7fh		; stop further interrupts
	mov	a, pcon			; inspect PCON after recovery from idle
	jnz	psave1			; PCON register should be clear

done:   jmp     waitg_tst

psave1: error	E_power_control
	;---------------------------------------------------------------------------
	;                             WAIT STATES TEST
	;---------------------------------------------------------------------------
waitg_tst:
	mov	a,config_reg		;Copy the configuration register to Acc
	jb	a.1,test_ok		;terminate the test if the timers are not present
	jb      a.2,test_ok              ;terminate the test if the ports are not present
	jmp	wait_test
test_ok:jmp	testok
        ;-------------------------------------------------------------
	;                     TIMER 0 SET UP 
	;-------------------------------------------------------------
wait_test:
        mov	tmod,#1  		;Make timer0 to operate as 16bits timer
	mov	tl0,#0			;clear TL0
	mov	th0,#0			;clear TH0
	mov     ie,#82h                 ;enable the Interrupt of the Timer0
	mov     tcon,#10h               ;Start the Timer0
	mov     a,#0                    ;clear Acc
	mov     r0,#0                   ;clear R0
	mov     r2,#10h                 ;Initialize counter R1
	;--------------------------------------------------------------
	;          PROGRAM WAIT STATES=1-15 - XRAM WAIT STATES=1-15
	;--------------------------------------------------------------
data:   inc	r0                      ;Increment R0
	mov     a,r0                    ;Load Acc with R0
	mov	dptr,#tbl1              ;Load DPTR with address of table tbl1
	movc    a,@a+dptr               ;Load Code Byte
	mov	wcon,a                  ;Introduce wait states 
	mov	a,#1                    ;Load Acc with one
	mov     dptr,#tbl2              ;Load DPTR with address of table tbl2  
	movc    a,@a+dptr               ;Copy Code Byte Indexed Addressing
	cjne    a,#2,errw1              ;Comapre Acc with 2
	mov     7fh,#10h                ;Load 7FH with 10h
	mov     a,#10h                  ;Load Acc with 10h
	add     a,7fh                   ;ADD Direct Addressing
        cjne    a,#20h,errw3            ;Compare Acc with 20h
	mov     r0,#80h                 ;Load R0 with 80h
	mov     @r0,#20h                ;Load address 80h with 20h
	orl     a,@r0                   ;ORL Indirect Addressing
        cjne    a,#20h,errw4            ;Compare Acc with 20h
	mov     r1,#10h                 ;Load R1 with 10h
	anl     a,r1                    ;ANL Register Addressing
	cjne    a,#0,errw5              ;Compare Acc with 0
	mov     a,#10d                  ;load Acc with 10h
	clr     c                       ;clear the carry
	subb    a,#2                    ;SUBB Imediate Constant
	cjne    a,#8d,errw6             ;Compare Acc with 8d
	djnz    r2,data                 ;Loop
	jmp     W_tst1  

tbl1:	db	00h
	db	01h
	db	12h
	db	23h
	db	34h
	db	45h
	db	56h
	db	67h
	db	78h
	db	89h
	db	9Ah
	db	ABh
	db	BCh
	db	CDh
	db	DEh
	db	EFh
	db	FFh
                  
tbl2:   db	00h
	db	02h
	db      04h
	db      06h
	db      08h

errw1:   sjmp    errw1			;error the MOVC instruction
errw3:   sjmp    errw3                  ;error in the ADD instruction
errw4:   sjmp    errw4                  ;error in the ORL instruction
errw5:   sjmp    errw5                  ;error in the ANL instruction
errw6:   sjmp    errw6                  ;error in the SUBB instruction
	;--------------------------------------------------------------
        ; stop the Timer0 and display its results  
	;--------------------------------------------------------------
W_tst1:	mov	tcon,#0			;stop the timer0
	mov     wcon,#0                 ;introduce zero wait states
	mov     p1,#0                   ;clear port1
	mov     p1,th0			;Copy TH0  to Port1
        mov     p1,tl0                  ;Copy TL0  to Port1
	mov	a,th0                   ;Copy TH0 to Acc
	cjne    a,#1ah,errw7            ;compare TH0 with 0DH
	mov     a,tl0                   ;Copy TL0 to Acc
	cjne    a,#dch,errw8            ;Compare TL0 with EFH
	;---------------------------------------------------------------
	;             TEST OF THE MOVX INSTRUCTIONS 
	;---------------------------------------------------------------
	mov	wcon, #23h              ;introduce some wait states
	mov     a,#02h			;copy 2 to Acc
	mov     dptr,#257d              ;Load DPTR with the value 257D                  
	movx    @dptr,a                 ;Copy Acc to 257D address
        movx    a,@dptr                 ;Read what has been written
	cjne    a,#2,errw9              ;Compare Acc with 2
	mov	wcon, #ABh              ;introduce some wait states
	mov     a,#04h			;copy 2 to Acc
	mov     dptr,#258d              ;Load DPTR with the value 258D                  
	movx    @dptr,a                 ;Copy Acc to 257D address
        movx    a,@dptr                 ;Read what has been written
	cjne    a,#4,errw10             ;Compare Acc with 2
	mov	wcon,#0                 ;introduce zero wait states
	jmp	testok

errw7:  sjmp    errw7                   ;error in the value of TH0
errw8:  sjmp    errw8                   ;error in the value of TL0
errw9:  sjmp    errw9                   ;error in the MOVX instructions
errw10: sjmp    errw10                  ;error in the MOVX instructions
;=============
ser_int_check:
;=============
;
; check serial interrupt
;
; entry: r6 contains data byte for transmission
;  exit: when a serial interrupt has occurred within timeout period
;	 if serial interrupt has not occurred by timeout the loop does not exit
;	 r1 corrupt, ie.4 reset
;
	mov	ie, #(ieenable + ieserialenable)
					; enable serial interrupt
	mov	sbuf, r6		; write data to be transmitted
	mov	r1, #ffh		; maximum number of attempts
$i0c10:	jnb	ie.4, $i0c30		; break out once interrupt is disabled
	djnz	r1, $i0c10		; repeat until timeout
;
; time out error waiting for serial interrupt
;
	mov	scon, #0		; stop interrupt
	error	E_ser_not_occurred
;
$i0c30: ret				; return to main thread
;
;==========
initialise:
;==========
;
; initialisation for test routine
;
	clr	a
	mov	reg0,a			; initialise register variables
	mov	reg1f,a
	mov	reg6f,a
acall:	acall	init_r0_r7		; test acall
ajmp:	ajmp	init_done		; test ajmp
errq:	sjmp    errq                    ; error ajmp failed 

init_done:
	nop
	ret
;
init_r0_r7:	mov	r0,a		; initialise r0 - r7
	mov	r1,a
	mov	r2,a
	mov	r3,a
	mov	r4,a
	mov	r5,a
	mov	r6,a
	mov	r7,a
	ret
;
ljmpret:
	ljmp	ljmpcont
	error	E_ljmp_bwd_failed
;
ret_int:	mov	a,#data55
	reti
;
;	==================
	org	Tst_OK
;	==================
;
;======
testok:	
;======
;
; reach this point if the tests in this module have run correctly
;
; entry: no conditions
;  exit: never
;
        mov	pcon,#01		;go to idle mode

	end				; end of source file
